/// <summary>
        /// Deep clones the ContributionsModel (no reference to original)
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static ContributionsModel Clone(this ContributionsModel source)
        {
            // Deep clone using json.net
            var json = JsonConvert.SerializeObject(source);

            return(JsonConvert.DeserializeObject <ContributionsModel>(json));
        }
예제 #2
0
 public ActionResult Statements(int id)
 {
     if(!DbUtil.Db.CurrentUserPerson.CanViewStatementFor(DbUtil.Db, id))
         return Content("No permission to view statement");
     var m = new ContributionsModel(id);
     return View("Giving/Statements", m);
 }
예제 #3
0
        public ActionResult Contributions(int id, int?page, int?size, string sort, string dir)
        {
            var m = new ContributionsModel(id);

            m.Pager.Set("/Person2/Contributions/" + id, page, size, sort, dir);
            return(View("Giving/Contributions", m));
        }
예제 #4
0
        /// <summary>
        /// Deleted s contribution
        /// </summary>
        /// <param name="contribution">Item to delete</param>
        /// <returns>Success or failure</returns>
        public async Task <bool?> DeleteContributionAsync(ContributionsModel contribution)
        {
            if (contribution == null)
            {
                throw new NullReferenceException("The contribution parameter was null.");
            }

            try
            {
                using (var response = await client.DeleteAsync($"https://mvpapi.azure-api.net/mvp/api/contributions?id={contribution.ContributionId}"))
                {
                    return(response.IsSuccessStatusCode);
                }
            }
            catch (HttpRequestException e)
            {
                if (e.Message.Contains("401"))
                {
                    //TODO Try refresh token, access token is only valid for 60 minutes
                }

                if (e.Message.Contains("500"))
                {
                }

                Debug.WriteLine($"UpdateContributionAsync HttpRequestException: {e}");
                return(null);
            }
            catch (Exception e)
            {
                Debug.WriteLine($"GetProfileAsync Exception: {e}");
                return(null);
            }
        }
예제 #5
0
 public ActionResult Statements(ContributionsModel m)
 {
     if (!DbUtil.Db.CurrentUserPerson.CanViewStatementFor(DbUtil.Db, m.PeopleId))
     {
         return(Content("No permission to view statement"));
     }
     return(View("Giving/Statements", m));
 }
        public static bool Compare(this ContributionsModel original, ContributionsModel selected)
        {
            try
            {
                if (original == null || selected == null)
                {
                    return(false);
                }

                if (selected.Title != original.Title)
                {
                    return(false);
                }

                if (selected.Description != original.Description)
                {
                    return(false);
                }

                if (selected.ReferenceUrl != original.ReferenceUrl)
                {
                    return(false);
                }

                if (selected.ContributionTechnology.Id != original.ContributionTechnology.Id)
                {
                    return(false);
                }

                if (selected.StartDate.Value.Date != original.StartDate.Value.Date)
                {
                    return(false);
                }

                if (selected.AnnualQuantity != original.AnnualQuantity)
                {
                    return(false);
                }

                if (selected.SecondAnnualQuantity != original.SecondAnnualQuantity)
                {
                    return(false);
                }

                if (selected.AnnualReach != original.AnnualReach)
                {
                    return(false);
                }
            }
            catch
            {
                return(false);
            }

            // If all comparisons pass, true to signify a perfect match
            return(true);
        }
예제 #7
0
        public ActionResult Statements(int id)
        {
            if (!DbUtil.Db.CurrentUserPerson.CanViewStatementFor(DbUtil.Db, id))
            {
                return(Content("No permission to view statement"));
            }
            var m = new ContributionsModel(id);

            return(View("Giving/Statements", m));
        }
예제 #8
0
        /// <summary>
        /// Updates an existing contribution, identified by the contribution ID
        /// </summary>
        /// <param name="contribution">Contribution to be updated</param>
        /// <returns>Bool to denote update success or failure</returns>
        public async Task <bool?> UpdateContributionAsync(ContributionsModel contribution)
        {
            if (contribution == null)
            {
                throw new NullReferenceException("The contribution parameter was null.");
            }

            try
            {
                // Request body
                var    serializedContribution = JsonConvert.SerializeObject(contribution);
                byte[] byteData = Encoding.UTF8.GetBytes(serializedContribution);

                using (var content = new ByteArrayContent(byteData))
                {
                    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

                    using (var response = await _client.PutAsync("https://mvpapi.azure-api.net/mvp/api/contributions", content))
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            return(true);
                        }
                        else
                        {
                            if (response.StatusCode == HttpStatusCode.Unauthorized || response.StatusCode == HttpStatusCode.Forbidden)
                            {
                                AccessTokenExpired?.Invoke(this, new EventArgs());
                            }
                        }
                    }
                }
            }
            catch (HttpRequestException e)
            {
                await e.LogExceptionAsync();

                if (e.Message.Contains("500"))
                {
                    RequestErrorOccurred?.Invoke(this, new EventArgs());
                }

                Debug.WriteLine($"UpdateContributionAsync HttpRequestException: {e}");
                return(null);
            }
            catch (Exception e)
            {
                await e.LogExceptionAsync();

                Debug.WriteLine($"GetProfileAsync Exception: {e}");
            }

            return(null);
        }
예제 #9
0
        public ContributionDetailViewModel(ContributionsModel contribution)
        {
            if (DesignerProperties.GetIsInDesignMode(new DependencyObject()))
            {
                Visibilities         = DesignTimeHelpers.GenerateVisibilities();
                SelectedContribution = DesignTimeHelpers.GenerateContributions().FirstOrDefault();
            }

            SelectedContribution = contribution;

            RemoveAdditionalTechAreaCommand = new DelegateCommand <ContributionTechnologyModel>(RemoveAdditionalArea);
        }
예제 #10
0
        public ActionResult Contributions(ContributionsModel m)
        {
            string userYear = m.Year;

            m = GetGivingUserPreferences(m);
            if (userYear != "YearToDate")
            {
                m.Year = userYear;
            }

            return(View("Giving/Contributions", m));
        }
예제 #11
0
        /// <summary>
        /// Submits a new contribution to the currently sign-in MVP profile
        /// </summary>
        /// <param name="contribution">The contribution to be submitted</param>
        /// <returns>Contribution submitted. This object should now have a valid ID and be added to the app's Contributions collection</returns>
        public async Task <ContributionsModel> SubmitContributionAsync(ContributionsModel contribution)
        {
            if (contribution == null)
            {
                throw new NullReferenceException("The contribution parameter was null.");
            }

            try
            {
                var    serializedContribution = JsonConvert.SerializeObject(contribution);
                byte[] byteData = Encoding.UTF8.GetBytes(serializedContribution);

                using (var content = new ByteArrayContent(byteData))
                {
                    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

                    using (var response = await client.PostAsync("https://mvpapi.azure-api.net/mvp/api/contributions?", content))
                    {
                        var json = await response.Content.ReadAsStringAsync();

                        Debug.WriteLine($"Submission Save JSON: {json}");

                        var result = JsonConvert.DeserializeObject <ContributionsModel>(json);

                        Debug.WriteLine($"Submission Save Result: ID {result.ContributionId}");

                        return(result);
                    }
                }
            }
            catch (HttpRequestException e)
            {
                if (e.Message.Contains("401"))
                {
                    //TODO Try refresh token, access token is only valid for 60 minutes
                }

                if (e.Message.Contains("500"))
                {
                }

                Debug.WriteLine($"SubmitContributionAsync HttpRequestException: {e}");
                return(null);
            }
            catch (Exception e)
            {
                Debug.WriteLine($"SubmitContributionAsync Exception: {e}");
                return(null);
            }
        }
예제 #12
0
        /// <summary>
        /// Updates an existing contribution, identified by the contribution ID
        /// </summary>
        /// <param name="contribution">Contribution to be updated</param>
        /// <returns>Bool to denote update success or failure</returns>
        public async Task <bool?> UpdateContributionAsync(ContributionsModel contribution)
        {
            if (contribution == null)
            {
                throw new NullReferenceException("The contribution parameter was null.");
            }

            try
            {
                // Request body
                var    serializedContribution = JsonConvert.SerializeObject(contribution);
                byte[] byteData = Encoding.UTF8.GetBytes(serializedContribution);

                using (var content = new ByteArrayContent(byteData))
                {
                    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

                    using (var response = await client.PutAsync("https://mvpapi.azure-api.net/mvp/api/contributions", content))
                    {
                        return(response.IsSuccessStatusCode);
                    }
                }
            }
            catch (HttpRequestException e)
            {
                await e.LogExceptionAsync();

                if (e.Message.Contains("401"))
                {
                    //TODO Try refresh token, access token is only valid for 60 minutes
                }

                if (e.Message.Contains("500"))
                {
                }

                Debug.WriteLine($"UpdateContributionAsync HttpRequestException: {e}");
                return(null);
            }
            catch (Exception e)
            {
                await e.LogExceptionWithUserMessage(
                    $"Sorry, there was a problem updating the contribution '{contribution.Title}'. If you'd like to send a technical summary to the app development team, click Yes.",
                    "Update Contribution Error");

                Debug.WriteLine($"GetProfileAsync Exception: {e}");
                return(null);
            }
        }
예제 #13
0
        public ActionResult Statements(ContributionsModel m)
        {
            if (!CurrentDatabase.CurrentUserPerson.CanViewStatementFor(CurrentDatabase, m.PeopleId))
            {
                return(Content("No permission to view statement"));
            }

            var hasCustomStatementsXml = CurrentDatabase.Content("CustomStatements", "") != string.Empty;
            var hasStandardFundLabel   = CurrentDatabase.Setting("StandardFundSetName", string.Empty) != string.Empty;
            var hasContributionFundStatementsEnabled = CurrentDatabase.Setting("EnableContributionFundsOnStatementDisplay", false);

            var useNewStatementView = hasCustomStatementsXml && hasStandardFundLabel && hasContributionFundStatementsEnabled;

            return(View(useNewStatementView ? "Giving/StatementsWithFund" : "Giving/Statements", m));
        }
예제 #14
0
    private void ExpandButton_Click(object sender, RoutedEventArgs e)
    {
        if (sender is Button btn && btn.DataContext is ContributionsModel contribution)
        {
            if (lastExpanded != null && lastExpanded == contribution)
            {
                ContributionsGrid.HideRowDetailsForItem(contribution);
            }
            else
            {
                ContributionsGrid.ShowRowDetailsForItem(contribution);
            }

            lastExpanded = contribution;
        }
    }
예제 #15
0
        /// <summary>
        /// Delete contribution
        /// </summary>
        /// <param name="contribution">Item to delete</param>
        /// <returns>Success or failure</returns>
        public async Task <bool?> DeleteContributionAsync(ContributionsModel contribution)
        {
            if (contribution == null)
            {
                throw new NullReferenceException("The contribution parameter was null.");
            }

            try
            {
                using (var response = await _client.DeleteAsync($"https://mvpapi.azure-api.net/mvp/api/contributions?id={contribution.ContributionId}"))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        return(true);
                    }
                    else
                    {
                        if (response.StatusCode == HttpStatusCode.Unauthorized || response.StatusCode == HttpStatusCode.Forbidden)
                        {
                            AccessTokenExpired?.Invoke(this, new EventArgs());
                        }
                    }
                }
            }
            catch (HttpRequestException e)
            {
                await e.LogExceptionAsync();

                if (e.Message.Contains("500"))
                {
                    RequestErrorOccurred?.Invoke(this, new EventArgs());
                }

                Debug.WriteLine($"UpdateContributionAsync HttpRequestException: {e}");
                return(null);
            }
            catch (Exception e)
            {
                await e.LogExceptionAsync();

                Debug.WriteLine($"GetProfileAsync Exception: {e}");
                return(null);
            }

            return(null);
        }
예제 #16
0
        /// <summary>
        /// Updates an existing contribution, identified by the contribution ID
        /// </summary>
        /// <param name="contribution">Contribution to be updated</param>
        /// <returns>Bool to denote update success or failure</returns>
        public async Task <bool?> UpdateContributionAsync(ContributionsModel contribution)
        {
            if (contribution == null)
            {
                throw new NullReferenceException("The contribution parameter was null.");
            }

            try
            {
                // Request body
                var    serializedContribution = JsonConvert.SerializeObject(contribution);
                byte[] byteData = Encoding.UTF8.GetBytes(serializedContribution);

                using (var content = new ByteArrayContent(byteData))
                {
                    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

                    using (var response = await client.PutAsync("https://mvpapi.azure-api.net/mvp/api/contributions", content))
                    {
                        return(response.IsSuccessStatusCode);
                    }
                }
            }
            catch (HttpRequestException e)
            {
                if (e.Message.Contains("401"))
                {
                    //TODO Try refresh token, access token is only valid for 60 minutes
                }

                if (e.Message.Contains("500"))
                {
                }

                Debug.WriteLine($"UpdateContributionAsync HttpRequestException: {e}");
                return(null);
            }
            catch (Exception e)
            {
                Debug.WriteLine($"GetProfileAsync Exception: {e}");
                return(null);
            }
        }
예제 #17
0
        /// <summary>
        /// Deleted s contribution
        /// </summary>
        /// <param name="contribution">Item to delete</param>
        /// <returns>Success or failure</returns>
        public async Task <bool?> DeleteContributionAsync(ContributionsModel contribution)
        {
            if (contribution == null)
            {
                throw new NullReferenceException("The contribution parameter was null.");
            }

            try
            {
                using (var response = await client.DeleteAsync($"https://mvpapi.azure-api.net/mvp/api/contributions?id={contribution.ContributionId}"))
                {
                    return(response.IsSuccessStatusCode);
                }
            }
            catch (HttpRequestException e)
            {
                await e.LogExceptionAsync();

                if (e.Message.Contains("401"))
                {
                    //TODO Try refresh token, access token is only valid for 60 minutes
                }

                if (e.Message.Contains("500"))
                {
                }

                Debug.WriteLine($"UpdateContributionAsync HttpRequestException: {e}");
                return(null);
            }
            catch (Exception e)
            {
                await e.LogExceptionWithUserMessage(
                    $"Sorry, there was a problem deleting the contribution '{contribution.Title}'. If you'd like to send a technical summary to the app development team, click Yes.",
                    "Delete Contribution Error");

                Debug.WriteLine($"GetProfileAsync Exception: {e}");
                return(null);
            }
        }
예제 #18
0
        private ContributionsModel GetGivingUserPreferences(ContributionsModel m)
        {
            var Year = GetUserHistory("Year");

            if (!string.IsNullOrEmpty(Year))
            {
                m.Year = Year;
            }

            var givingsummary = GetUserHistory("givingsummary");

            if (!string.IsNullOrEmpty(givingsummary))
            {
                m.givingSumCollapse = givingsummary.ToBool();
            }

            var pledgesummary = GetUserHistory("pledgesummary");

            if (!string.IsNullOrEmpty(pledgesummary))
            {
                m.pledgeSumCollapse = pledgesummary.ToBool();
            }

            var givingdetail = GetUserHistory("givingdetail");

            if (!string.IsNullOrEmpty(givingdetail))
            {
                m.givingDetCollapse = givingdetail.ToBool();
            }

            var pledgedetail = GetUserHistory("pledgedetail");

            if (!string.IsNullOrEmpty(pledgedetail))
            {
                m.pledgeDetCollapse = pledgedetail.ToBool();
            }

            return(m);
        }
예제 #19
0
 /// <summary>
 /// Creates a new Contribution item
 /// </summary>
 /// <param name='operations'>
 /// The operations group for this extension method.
 /// </param>
 /// <param name='subscriptionKey'>
 /// subscription key in url
 /// </param>
 /// <param name='ocpApimSubscriptionKey'>
 /// subscription key in header
 /// </param>
 /// <param name='contributionsModel'>
 /// ContributionsModel object
 /// </param>
 /// <param name='cancellationToken'>
 /// The cancellation token.
 /// </param>
 public static async Task <object> PostContributionAsync(this IMVPProduction operations, string subscriptionKey = default(string), string ocpApimSubscriptionKey = default(string), ContributionsModel contributionsModel = default(ContributionsModel), CancellationToken cancellationToken = default(CancellationToken))
 {
     using (var _result = await operations.PostContributionWithHttpMessagesAsync(subscriptionKey, ocpApimSubscriptionKey, contributionsModel, null, cancellationToken).ConfigureAwait(false))
     {
         return(_result.Body);
     }
 }
예제 #20
0
 /// <summary>
 /// Creates a new Contribution item
 /// </summary>
 /// <param name='operations'>
 /// The operations group for this extension method.
 /// </param>
 /// <param name='subscriptionKey'>
 /// subscription key in url
 /// </param>
 /// <param name='ocpApimSubscriptionKey'>
 /// subscription key in header
 /// </param>
 /// <param name='contributionsModel'>
 /// ContributionsModel object
 /// </param>
 public static object PostContribution(this IMVPProduction operations, string subscriptionKey = default(string), string ocpApimSubscriptionKey = default(string), ContributionsModel contributionsModel = default(ContributionsModel))
 {
     return(Task.Factory.StartNew(s => ((IMVPProduction)s).PostContributionAsync(subscriptionKey, ocpApimSubscriptionKey, contributionsModel), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult());
 }
예제 #21
0
 /// <summary>
 /// Updates a Contribution item
 /// </summary>
 /// <param name='operations'>
 /// The operations group for this extension method.
 /// </param>
 /// <param name='subscriptionKey'>
 /// subscription key in url
 /// </param>
 /// <param name='ocpApimSubscriptionKey'>
 /// subscription key in header
 /// </param>
 /// <param name='contributionsModel'>
 /// ContributionsModel object
 /// </param>
 /// <param name='cancellationToken'>
 /// The cancellation token.
 /// </param>
 public static async Task PutContributionAsync(this IMVPProduction operations, string subscriptionKey = default(string), string ocpApimSubscriptionKey = default(string), ContributionsModel contributionsModel = default(ContributionsModel), CancellationToken cancellationToken = default(CancellationToken))
 {
     await operations.PutContributionWithHttpMessagesAsync(subscriptionKey, ocpApimSubscriptionKey, contributionsModel, null, cancellationToken).ConfigureAwait(false);
 }
예제 #22
0
        /// <summary>
        /// Submits a new contribution to the currently sign-in MVP profile
        /// </summary>
        /// <param name="contribution">The contribution to be submitted</param>
        /// <returns>Contribution submitted. This object should now have a valid ID and be added to the app's Contributions collection</returns>
        public async Task <ContributionsModel> SubmitContributionAsync(ContributionsModel contribution)
        {
            if (contribution == null)
            {
                throw new NullReferenceException("The contribution parameter was null.");
            }

            try
            {
                var    serializedContribution = JsonConvert.SerializeObject(contribution);
                byte[] byteData = Encoding.UTF8.GetBytes(serializedContribution);

                using (var content = new ByteArrayContent(byteData))
                {
                    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

                    using (var response = await client.PostAsync("https://mvpapi.azure-api.net/mvp/api/contributions?", content))
                    {
                        var json = await response.Content.ReadAsStringAsync();

                        Debug.WriteLine($"Submission Save JSON: {json}");

                        var result = JsonConvert.DeserializeObject <ContributionsModel>(json);

                        Debug.WriteLine($"Submission Save Result: ID {result.ContributionId}");

                        return(result);
                    }
                }
            }
            catch (HttpRequestException e)
            {
                await e.LogExceptionAsync();

                if (e.Message.Contains("401"))
                {
                    //TODO Try refresh token, access token is only valid for 60 minutes
                }

                if (e.Message.Contains("500"))
                {
                }

                Debug.WriteLine($"SubmitContributionAsync HttpRequestException: {e}");
                return(null);
            }
            catch (Exception e)
            {
                if (e.Message.Contains("Error converting value"))
                {
                    await e.LogExceptionWithUserMessage(
                        $"There was an invalid value for one of the submissions fields and the API rejected it. See the error message below for more details, make the adjustment and save it again:\r\n\n" +
                        $"{e.Message}",
                        "Submit Contribution Error");
                }
                else
                {
                    await e.LogExceptionWithUserMessage(
                        $"Sorry, there was an unexpected problem uploading the contribution '{contribution.Title}'. If you'd like to send a technical summary to the app development team, click Yes.",
                        "Submit Contribution Error");
                }

                Debug.WriteLine($"SubmitContributionAsync Exception: {e}");

                return(null);
            }
        }
예제 #23
0
 public ActionResult Contributions(int id, int? page, int? size, string sort, string dir)
 {
     var m = new ContributionsModel(id);
     m.Pager.Set("/Person2/Contributions/" + id, page, size, sort, dir);
     return View("Giving/Contributions", m);
 }
예제 #24
0
 public ActionResult Statements(ContributionsModel m)
 {
     if (!DbUtil.Db.CurrentUserPerson.CanViewStatementFor(DbUtil.Db, m.PeopleId))
         return Content("No permission to view statement");
     return View("Giving/Statements", m);
 }
예제 #25
0
 public ActionResult Contributions(ContributionsModel m)
 {
     return View("Giving/Contributions", m);
 }
예제 #26
0
        /// <summary>
        /// Validates the values of a ContributionsModel instance.
        /// </summary>
        /// <param name="contribution">The contribution to be validated</param>
        /// <param name="showErrorMessage">show the user an error message with the field name of the missing value.
        /// The default is False (quick validation mode). Set to True when you're about to save the contribution.
        /// </param>
        /// <returns>Boolean that denotes a successful validation</returns>
        public static async Task <bool> Validate(this ContributionsModel contribution, bool showErrorMessage = false)
        {
            if (contribution == null)
            {
                throw new NullReferenceException("The contribution was null");
            }

            var isValid         = true;
            var failedFieldName = "";

            // Check title
            if (string.IsNullOrEmpty(contribution?.Title))
            {
                failedFieldName = "Title";
                isValid         = false;
            }

            if (contribution.ContributionType == null)
            {
                failedFieldName = "Contribution Type";
                isValid         = false;
            }

            // Check the contribution area
            if (contribution.ContributionTechnology == null)
            {
                failedFieldName = "Contribution Technology";
                isValid         = false;
            }

            // *** ContributionType Specific Condition ***

            // Gets a Tuple that contains the specific conditions of a chosen ContributionType
            var typeRequirements = contribution.ContributionType.GetContributionTypeRequirements(); //contribution.ContributionType.GetContributionTypeRequirementsById();

            // Check Url
            if (string.IsNullOrEmpty(contribution.ReferenceUrl) && typeRequirements.Item4)
            {
                failedFieldName = "url";
                isValid         = false;
            }

            // Check AnnualQuantity
            if (contribution.AnnualQuantity == null && !string.IsNullOrEmpty(typeRequirements.Item1))
            {
                failedFieldName = "First Quantity";
                isValid         = false;
            }

            // Check SecondAnnualQuantity
            if (contribution.SecondAnnualQuantity == null && !string.IsNullOrEmpty(typeRequirements.Item2))
            {
                failedFieldName = "Second Quantity";
                isValid         = false;
            }

            // Check AnnualReach
            if (contribution.AnnualReach == null && !string.IsNullOrEmpty(typeRequirements.Item3))
            {
                failedFieldName = "Annual Reach";
                isValid         = false;
            }

            // *** end of ContributionType check ***

            // Check Visibility
            if (contribution.Visibility == null)
            {
                failedFieldName = "Visibility";
                isValid         = false;
            }

            // If we're using this extension method for final validation and not fast validation, show error message to user
            if (!isValid && showErrorMessage)
            {
                await new MessageDialog($"The {failedFieldName} field is a required entry for this contribution type.").ShowAsync();
            }

            return(isValid);
        }
예제 #27
0
 public ActionResult Contributions(ContributionsModel m)
 {
     return(View("Giving/Contributions", m));
 }
예제 #28
0
        /// <summary>
        /// Validates the values of a ContributionsModel instance.
        /// </summary>
        /// <param name="contribution">The contribution to be validated</param>
        /// <returns>The bool parameter denotes a successful validation. If unsuccessful, the string parameter will have the name of the field that is incomplete</returns>
        public static Tuple <bool, string> Validate(this ContributionsModel contribution)
        {
            if (contribution == null)
            {
                throw new NullReferenceException("The contribution was null");
            }

            var isValid         = true;
            var failedFieldName = "";

            // Check title
            if (string.IsNullOrEmpty(contribution?.Title))
            {
                failedFieldName = "Title";
                isValid         = false;
            }

            if (contribution.ContributionType == null)
            {
                failedFieldName = "Contribution Type";
                isValid         = false;
            }

            // Check the contribution area
            if (contribution.ContributionTechnology == null)
            {
                failedFieldName = "Contribution Technology";
                isValid         = false;
            }

            // *** ContributionType Specific Condition ***

            // Gets a Tuple that contains the specific conditions of a chosen ContributionType
            var typeRequirements = contribution.ContributionType.GetContributionTypeRequirements(); //contribution.ContributionType.GetContributionTypeRequirementsById();

            // Check Url
            if (string.IsNullOrEmpty(contribution.ReferenceUrl) && typeRequirements.Item4)
            {
                failedFieldName = "url";
                isValid         = false;
            }

            // Check AnnualQuantity
            if (contribution.AnnualQuantity == null && !string.IsNullOrEmpty(typeRequirements.Item1))
            {
                failedFieldName = "First Quantity";
                isValid         = false;
            }

            // Check SecondAnnualQuantity
            if (contribution.SecondAnnualQuantity == null && !string.IsNullOrEmpty(typeRequirements.Item2))
            {
                failedFieldName = "Second Quantity";
                isValid         = false;
            }

            // Check AnnualReach
            if (contribution.AnnualReach == null && !string.IsNullOrEmpty(typeRequirements.Item3))
            {
                failedFieldName = "Annual Reach";
                isValid         = false;
            }

            // *** end of ContributionType check ***

            // Check Visibility
            if (contribution.Visibility == null)
            {
                failedFieldName = "Visibility";
                isValid         = false;
            }

            return(new Tuple <bool, string>(isValid, failedFieldName));
        }