/// <summary> /// Validates the Gift Detail data. /// </summary> /// <param name="AContext">Context that describes where the data validation failed.</param> /// <param name="ARow">The <see cref="DataRow" /> which holds the the data against which the validation is run.</param> /// <param name="AVerificationResultCollection">Will be filled with any <see cref="TVerificationResult" /> items if /// data validation errors occur.</param> /// <param name="AValidationControlsDict">A <see cref="TValidationControlsDict" /> containing the Controls that /// display data that is about to be validated.</param> /// <param name="ARecipientPartnerClass">Recipient's Partner Class (used for Motivation Detail validation).</param> /// <param name="ASetupForILT">Optional - Is the recipient set up for inter-ledger transfers.</param> /// <param name="ACostCentres">Optional - a CostCentres table. Is required for import validation. </param> /// <param name="AAccounts">Optional - a Accounts table. Is required for import validation. </param> /// <param name="AMotivationGroups">Optional - a MotivationGroups table. Is required for import validation. </param> /// <param name="AMotivationDetails">Optional - a MotivationDetails table. Is required for import validation. </param> /// <param name="AMailingTable">Optional - a Mailing table. Is required for import validation. </param> /// <param name="ARecipientField">Optional The recipient field for the gift. Is required for import validation. </param> /// <returns>True if the validation found no data validation errors, otherwise false.</returns> public static bool ValidateGiftDetailManual(object AContext, GiftBatchTDSAGiftDetailRow ARow, ref TVerificationResultCollection AVerificationResultCollection, TValidationControlsDict AValidationControlsDict, TPartnerClass? ARecipientPartnerClass, bool? ASetupForILT = null, ACostCentreTable ACostCentres = null, AAccountTable AAccounts = null, AMotivationGroupTable AMotivationGroups = null, AMotivationDetailTable AMotivationDetails = null, PMailingTable AMailingTable = null, Int64 ARecipientField = -1) { DataColumn ValidationColumn; TValidationControlsData ValidationControlsData; TVerificationResult VerificationResult = null; object ValidationContext; int VerifResultCollAddedCount = 0; bool ValidPartner = true; // Don't validate deleted DataRows if (ARow.RowState == DataRowState.Deleted) { return true; } bool isImporting = AContext.ToString().Contains("Importing"); // Check if valid recipient ValidationColumn = ARow.Table.Columns[AGiftDetailTable.ColumnRecipientKeyId]; ValidationContext = String.Format("Batch no. {0}, gift no. {1}, detail no. {2}", ARow.BatchNumber, ARow.GiftTransactionNumber, ARow.DetailNumber); VerificationResult = TSharedPartnerValidation_Partner.IsValidPartner( ARow.RecipientKey, new TPartnerClass[] { TPartnerClass.FAMILY, TPartnerClass.UNIT }, true, isImporting ? Catalog.GetString("Recipient key") : "Recipient of " + THelper.NiceValueDescription(ValidationContext.ToString()), AContext, ValidationColumn, null); if (VerificationResult != null) { AVerificationResultCollection.Remove(ValidationColumn); AVerificationResultCollection.AddAndIgnoreNullValue(VerificationResult); ValidPartner = false; } // 'Gift amount must be non-zero ValidationColumn = ARow.Table.Columns[AGiftDetailTable.ColumnGiftTransactionAmountId]; ValidationContext = String.Format("Batch Number {0} (transaction:{1} detail:{2})", ARow.BatchNumber, ARow.GiftTransactionNumber, ARow.DetailNumber); if (AValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData)) { VerificationResult = TNumericalChecks.IsNonZeroDecimal(ARow.GiftTransactionAmount, ValidationControlsData.ValidationControlLabel + (isImporting ? String.Empty : " of " + ValidationContext), AContext, ValidationColumn, ValidationControlsData.ValidationControl); // Handle addition/removal to/from TVerificationResultCollection if (AVerificationResultCollection.Auto_Add_Or_AddOrRemove(AContext, VerificationResult, ValidationColumn, true)) { VerifResultCollAddedCount++; } } // If recipient is non-zero, field must also be non-zero. Only check for valid recipient keys. ValidationColumn = ARow.Table.Columns[AGiftDetailTable.ColumnRecipientLedgerNumberId]; ValidationContext = String.Format("batch:{0} transaction:{1} detail:{2}", ARow.BatchNumber, ARow.GiftTransactionNumber, ARow.DetailNumber); if (AValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData)) { if ((ARow.RecipientKey > 0) && ValidPartner && (ARow.RecipientLedgerNumber == 0)) { VerificationResult = TNumericalChecks.IsGreaterThanZero(ARow.RecipientLedgerNumber, "Recipient field of " + ValidationContext + " is 0", AContext, ValidationColumn, ValidationControlsData.ValidationControl); // Handle addition/removal to/from TVerificationResultCollection if (AVerificationResultCollection.Auto_Add_Or_AddOrRemove(AContext, VerificationResult, ValidationColumn, true)) { VerifResultCollAddedCount++; } } // Motivation Group code must exist if (!ARow.IsMotivationGroupCodeNull() && (AMotivationGroups != null)) { AMotivationGroupRow foundRow = (AMotivationGroupRow)AMotivationGroups.Rows.Find( new object[] { ARow.LedgerNumber, ARow.MotivationGroupCode }); if ((foundRow == null) && AVerificationResultCollection.Auto_Add_Or_AddOrRemove( AContext, new TVerificationResult(ValidationContext, String.Format(Catalog.GetString("Unknown motivation group code '{0}'."), ARow.MotivationGroupCode), TResultSeverity.Resv_Critical), ValidationColumn)) { VerifResultCollAddedCount++; } } } if (!isImporting) { // NOTE AlanP Oct 2014. This gets checked by standard validation so may no longer be necessary? // (There was a bug in standard validation where NULL and empty string checks did not quite work as they should ... // so maybe this was necessary before. Anyway I am leaving it in for now. I know that importing works fine, // but maybe it is necessary in other circumstances?) // Motivation Detail must not be null ValidationColumn = ARow.Table.Columns[AGiftDetailTable.ColumnMotivationDetailCodeId]; ValidationContext = String.Format("(batch:{0} transaction:{1} detail:{2})", ARow.BatchNumber, ARow.GiftTransactionNumber, ARow.DetailNumber); if (AValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData)) { if (ARow.IsMotivationDetailCodeNull() || (ARow.MotivationDetailCode == String.Empty)) { VerificationResult = TGeneralChecks.ValueMustNotBeNullOrEmptyString(ARow.MotivationDetailCode, (isImporting ? ValidationControlsData.ValidationControlLabel : "Motivation Detail code " + ValidationContext), AContext, ValidationColumn, ValidationControlsData.ValidationControl); // Handle addition/removal to/from TVerificationResultCollection if (AVerificationResultCollection.Auto_Add_Or_AddOrRemove(AContext, VerificationResult, ValidationColumn, true)) { VerifResultCollAddedCount++; } } } } // Motivation Detail must be valid ValidationColumn = ARow.Table.Columns[AGiftDetailTable.ColumnMotivationDetailCodeId]; ValidationContext = String.Format("(batch:{0} transaction:{1} detail:{2})", ARow.BatchNumber, ARow.GiftTransactionNumber, ARow.DetailNumber); if (!ARow.IsMotivationDetailCodeNull() && (AMotivationDetails != null)) { AMotivationDetailRow foundRow = (AMotivationDetailRow)AMotivationDetails.Rows.Find( new object[] { ARow.LedgerNumber, ARow.MotivationGroupCode, ARow.MotivationDetailCode }); if ((foundRow == null) && AVerificationResultCollection.Auto_Add_Or_AddOrRemove( AContext, new TVerificationResult(ValidationContext, String.Format(Catalog.GetString("Unknown motivation detail code '{0}' for group '{1}'."), ARow.MotivationDetailCode, ARow.MotivationGroupCode), TResultSeverity.Resv_Critical), ValidationColumn)) { VerifResultCollAddedCount++; } if ((foundRow != null) && (foundRow.MotivationStatus == false) && AVerificationResultCollection.Auto_Add_Or_AddOrRemove( AContext, new TVerificationResult(ValidationContext, String.Format(Catalog.GetString("Motivation detail code '{0}' is no longer in use."), ARow.MotivationDetailCode), TResultSeverity.Resv_Critical), ValidationColumn)) { VerifResultCollAddedCount++; } if ((foundRow != null) && (foundRow.RecipientKey != 0) && (ARow.RecipientKey != 0) && (foundRow.RecipientKey != ARow.RecipientKey) && AVerificationResultCollection.Auto_Add_Or_AddOrRemove( AContext, new TVerificationResult(ValidationContext, String.Format(Catalog.GetString( "The recipient partner key for motivation detail code '{0}' does not match the recipient partner key in the import line."), ARow.MotivationDetailCode), TResultSeverity.Resv_Critical), ValidationColumn)) { VerifResultCollAddedCount++; } } // Motivation Detail must not be 'Field' or 'Keymin' if the recipient is a Family partner ValidationColumn = ARow.Table.Columns[AGiftDetailTable.ColumnMotivationDetailCodeId]; ValidationContext = String.Format("(batch:{0} transaction:{1} detail:{2})", ARow.BatchNumber, ARow.GiftTransactionNumber, ARow.DetailNumber); if (!ARow.IsMotivationDetailCodeNull() && (ARow.MotivationGroupCode == MFinanceConstants.MOTIVATION_GROUP_GIFT) && (ARecipientPartnerClass != null) && ((ARow.MotivationDetailCode == MFinanceConstants.GROUP_DETAIL_FIELD) || (ARow.MotivationDetailCode == MFinanceConstants.GROUP_DETAIL_KEY_MIN)) && (ARecipientPartnerClass == TPartnerClass.FAMILY)) { if (AValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData)) { VerificationResult = new TVerificationResult(AContext, String.Format(Catalog.GetString("Motivation Detail code '{0}' is not allowed for Family recipients."), ARow.MotivationDetailCode), TResultSeverity.Resv_Critical); if (AVerificationResultCollection.Auto_Add_Or_AddOrRemove(AContext, new TScreenVerificationResult(VerificationResult, ValidationColumn, ValidationControlsData.ValidationControl), ValidationColumn, true)) { VerifResultCollAddedCount++; } } } // Cost Centre Code must exist and be active. Only required for importing because the GUI does this for us otherwise. if (isImporting && (ACostCentres != null) && !ARow.IsCostCentreCodeNull()) { ValidationColumn = ARow.Table.Columns[AGiftDetailTable.ColumnCostCentreCodeId]; ValidationContext = ARow.CostCentreCode; if (AValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData)) { // We even need to check that the code exists! DataRow foundRow = ACostCentres.Rows.Find(new object[] { ARow.LedgerNumber, ARow.CostCentreCode }); if ((foundRow == null) && AVerificationResultCollection.Auto_Add_Or_AddOrRemove( AContext, new TScreenVerificationResult(ValidationContext, ValidationColumn, String.Format(Catalog.GetString("Unknown cost centre code '{0}'."), ARow.CostCentreCode), ValidationControlsData.ValidationControl, TResultSeverity.Resv_Critical), /* * new TVerificationResult(ValidationContext, * String.Format(Catalog.GetString("Unknown cost centre code '{0}'."), ARow.CostCentreCode), * TResultSeverity.Resv_Critical), */ ValidationColumn)) { VerifResultCollAddedCount++; } VerificationResult = (TScreenVerificationResult)TStringChecks.ValidateValueIsActive(ARow.LedgerNumber, ACostCentres, ValidationContext.ToString(), ACostCentreTable.GetCostCentreActiveFlagDBName(), AContext, ValidationColumn, ValidationControlsData.ValidationControl); // Handle addition/removal to/from TVerificationResultCollection if ((VerificationResult != null) && AVerificationResultCollection.Auto_Add_Or_AddOrRemove(AContext, VerificationResult, ValidationColumn, true)) { VerifResultCollAddedCount++; } } } // Account Code must exist and be active. Only required for importing because the GUI does this for us otherwise. if (isImporting && (AAccounts != null) && !ARow.IsAccountCodeNull()) { DataColumn[] ValidationColumns = new DataColumn[] { ARow.Table.Columns[AGiftDetailTable.ColumnAccountCodeId], ARow.Table.Columns[AGiftDetailTable.ColumnTaxDeductibleAccountCodeId] }; string[] AccountCodes = new string[] { ARow.AccountCode, ARow.TaxDeductibleAccountCode }; for (int i = 0; i < 2; i++) { if (AValidationControlsDict.TryGetValue(ValidationColumns[i], out ValidationControlsData)) { // We even need to check that the code exists! DataRow foundRow = AAccounts.Rows.Find(new object[] { ARow.LedgerNumber, AccountCodes[i] }); if ((foundRow == null) && AVerificationResultCollection.Auto_Add_Or_AddOrRemove( AContext, new TVerificationResult(AccountCodes[i], String.Format(Catalog.GetString("Unknown account code '{0}'."), AccountCodes[i]), TResultSeverity.Resv_Critical), ValidationColumns[i])) { VerifResultCollAddedCount++; } VerificationResult = (TScreenVerificationResult)TStringChecks.ValidateValueIsActive(ARow.LedgerNumber, AAccounts, AccountCodes[i], AAccountTable.GetAccountActiveFlagDBName(), AContext, ValidationColumns[i], ValidationControlsData.ValidationControl); // Handle addition/removal to/from TVerificationResultCollection if ((VerificationResult != null) && AVerificationResultCollection.Auto_Add_Or_AddOrRemove(AContext, VerificationResult, ValidationColumns[i], true)) { VerifResultCollAddedCount++; } } } } // Mailing code must exist ValidationColumn = ARow.Table.Columns[AGiftDetailTable.ColumnMailingCodeId]; ValidationContext = String.Format("(batch:{0} transaction:{1} detail:{2})", ARow.BatchNumber, ARow.GiftTransactionNumber, ARow.DetailNumber); if (!ARow.IsMailingCodeNull() && (AMailingTable != null)) { PMailingRow foundRow = (PMailingRow)AMailingTable.Rows.Find(ARow.MailingCode); if ((foundRow == null) && AVerificationResultCollection.Auto_Add_Or_AddOrRemove( AContext, new TVerificationResult(ValidationContext, String.Format(Catalog.GetString("Unknown mailing code '{0}'."), ARow.MailingCode), TResultSeverity.Resv_Critical), ValidationColumn)) { VerifResultCollAddedCount++; } } // Detail comments type 1 must not be null if associated comment is not null ValidationColumn = ARow.Table.Columns[AGiftDetailTable.ColumnCommentOneTypeId]; ValidationContext = String.Format("(batch:{0} transaction:{1} detail:{2})", ARow.BatchNumber, ARow.GiftTransactionNumber, ARow.DetailNumber); if (AValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData)) { if (!ARow.IsGiftCommentOneNull() && (ARow.GiftCommentOne != String.Empty)) { VerificationResult = TGeneralChecks.ValueMustNotBeNullOrEmptyString(ARow.CommentOneType, (isImporting ? ValidationControlsData.ValidationControlLabel : "Comment 1 type " + ValidationContext), AContext, ValidationColumn, ValidationControlsData.ValidationControl); // Handle addition/removal to/from TVerificationResultCollection if (AVerificationResultCollection.Auto_Add_Or_AddOrRemove(AContext, VerificationResult, ValidationColumn, true)) { VerifResultCollAddedCount++; } if (VerificationResult == null) { // There is a comment type for the comment - but it needs to be one of the valid types if ((ARow.CommentOneType != MFinanceConstants.GIFT_COMMENT_TYPE_DONOR) && (ARow.CommentOneType != MFinanceConstants.GIFT_COMMENT_TYPE_RECIPIENT) && (ARow.CommentOneType != MFinanceConstants.GIFT_COMMENT_TYPE_BOTH) && (ARow.CommentOneType != MFinanceConstants.GIFT_COMMENT_TYPE_OFFICE) && AVerificationResultCollection.Auto_Add_Or_AddOrRemove( AContext, new TVerificationResult(ValidationContext, String.Format(Catalog.GetString("Comment type must be one of '{0}', '{1}', '{2}' or '{3}'."), MFinanceConstants.GIFT_COMMENT_TYPE_DONOR, MFinanceConstants.GIFT_COMMENT_TYPE_RECIPIENT, MFinanceConstants.GIFT_COMMENT_TYPE_BOTH, MFinanceConstants.GIFT_COMMENT_TYPE_OFFICE), TResultSeverity.Resv_Critical), ValidationColumn)) { VerifResultCollAddedCount++; } } } } // Detail comments type 2 must not be null if associated comment is not null ValidationColumn = ARow.Table.Columns[AGiftDetailTable.ColumnCommentTwoTypeId]; ValidationContext = String.Format("(batch:{0} transaction:{1} detail:{2})", ARow.BatchNumber, ARow.GiftTransactionNumber, ARow.DetailNumber); if (AValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData)) { if (!ARow.IsGiftCommentTwoNull() && (ARow.GiftCommentTwo != String.Empty)) { VerificationResult = TGeneralChecks.ValueMustNotBeNullOrEmptyString(ARow.CommentTwoType, (isImporting ? ValidationControlsData.ValidationControlLabel : "Comment 2 type " + ValidationContext), AContext, ValidationColumn, ValidationControlsData.ValidationControl); // Handle addition/removal to/from TVerificationResultCollection if (AVerificationResultCollection.Auto_Add_Or_AddOrRemove(AContext, VerificationResult, ValidationColumn, true)) { VerifResultCollAddedCount++; } if (VerificationResult == null) { // There is a comment type for the comment - but it needs to be one of the valid types if ((ARow.CommentTwoType != MFinanceConstants.GIFT_COMMENT_TYPE_DONOR) && (ARow.CommentTwoType != MFinanceConstants.GIFT_COMMENT_TYPE_RECIPIENT) && (ARow.CommentTwoType != MFinanceConstants.GIFT_COMMENT_TYPE_BOTH) && (ARow.CommentTwoType != MFinanceConstants.GIFT_COMMENT_TYPE_OFFICE) && AVerificationResultCollection.Auto_Add_Or_AddOrRemove( AContext, new TVerificationResult(ValidationContext, String.Format(Catalog.GetString("Comment type must be one of '{0}', '{1}', '{2}' or '{3}'."), MFinanceConstants.GIFT_COMMENT_TYPE_DONOR, MFinanceConstants.GIFT_COMMENT_TYPE_RECIPIENT, MFinanceConstants.GIFT_COMMENT_TYPE_BOTH, MFinanceConstants.GIFT_COMMENT_TYPE_OFFICE), TResultSeverity.Resv_Critical), ValidationColumn)) { VerifResultCollAddedCount++; } } } } // Detail comments type 3 must not be null if associated comment is not null ValidationColumn = ARow.Table.Columns[AGiftDetailTable.ColumnCommentThreeTypeId]; ValidationContext = String.Format("(batch:{0} transaction:{1} detail:{2})", ARow.BatchNumber, ARow.GiftTransactionNumber, ARow.DetailNumber); if (AValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData)) { if (!ARow.IsGiftCommentThreeNull() && (ARow.GiftCommentThree != String.Empty)) { VerificationResult = TGeneralChecks.ValueMustNotBeNullOrEmptyString(ARow.CommentThreeType, (isImporting ? ValidationControlsData.ValidationControlLabel : "Comment 3 type " + ValidationContext), AContext, ValidationColumn, ValidationControlsData.ValidationControl); // Handle addition/removal to/from TVerificationResultCollection if (AVerificationResultCollection.Auto_Add_Or_AddOrRemove(AContext, VerificationResult, ValidationColumn, true)) { VerifResultCollAddedCount++; } if (VerificationResult == null) { // There is a comment type for the comment - but it needs to be one of the valid types if ((ARow.CommentThreeType != MFinanceConstants.GIFT_COMMENT_TYPE_DONOR) && (ARow.CommentThreeType != MFinanceConstants.GIFT_COMMENT_TYPE_RECIPIENT) && (ARow.CommentThreeType != MFinanceConstants.GIFT_COMMENT_TYPE_BOTH) && (ARow.CommentThreeType != MFinanceConstants.GIFT_COMMENT_TYPE_OFFICE) && AVerificationResultCollection.Auto_Add_Or_AddOrRemove( AContext, new TVerificationResult(ValidationContext, String.Format(Catalog.GetString("Comment type must be one of '{0}', '{1}', '{2}' or '{3}'."), MFinanceConstants.GIFT_COMMENT_TYPE_DONOR, MFinanceConstants.GIFT_COMMENT_TYPE_RECIPIENT, MFinanceConstants.GIFT_COMMENT_TYPE_BOTH, MFinanceConstants.GIFT_COMMENT_TYPE_OFFICE), TResultSeverity.Resv_Critical), ValidationColumn)) { VerifResultCollAddedCount++; } } } } return VerifResultCollAddedCount == 0; }
/// <summary> /// Call from ShowDetailsManual after ACurrentDetailRow is known to be non-NULL /// </summary> public static void FinishShowDetailsManual(GiftBatchTDSAGiftDetailRow ACurrentDetailRow, TCmbAutoPopulated ACmbMotivationDetailCode, TtxtAutoPopulatedButtonLabel ATxtDetailRecipientKey, TtxtAutoPopulatedButtonLabel AtxtDetailRecipientLedgerNumber, TextBox ATxtDetailCostCentreCode, TextBox ATxtDetailAccountCode, ref string AMotivationGroup, ref string AMotivationDetail, out bool ? AEnableRecipientGiftDestination) { AEnableRecipientGiftDestination = null; //Record current values for motivation AMotivationGroup = ACurrentDetailRow.MotivationGroupCode; AMotivationDetail = ACurrentDetailRow.MotivationDetailCode; if (ACurrentDetailRow.IsCostCentreCodeNull()) { ATxtDetailCostCentreCode.Text = string.Empty; } else { ATxtDetailCostCentreCode.Text = ACurrentDetailRow.CostCentreCode; } if (ACurrentDetailRow.IsAccountCodeNull()) { ATxtDetailAccountCode.Text = string.Empty; } else { ATxtDetailAccountCode.Text = ACurrentDetailRow.AccountCode; } if (ACurrentDetailRow.IsRecipientKeyNull()) { ATxtDetailRecipientKey.Text = String.Format("{0:0000000000}", 0); UpdateRecipientKeyText(0, ACurrentDetailRow, AMotivationGroup, AMotivationDetail); } else { ATxtDetailRecipientKey.Text = String.Format("{0:0000000000}", ACurrentDetailRow.RecipientKey); UpdateRecipientKeyText(ACurrentDetailRow.RecipientKey, ACurrentDetailRow, AMotivationGroup, AMotivationDetail); } if (Convert.ToInt64(ATxtDetailRecipientKey.Text) == 0) { OnRecipientPartnerClassChanged(null, ATxtDetailRecipientKey, AtxtDetailRecipientLedgerNumber, out AEnableRecipientGiftDestination); } if (Convert.ToInt64(AtxtDetailRecipientLedgerNumber.Text) == 0) { OnRecipientPartnerClassChanged(ATxtDetailRecipientKey.CurrentPartnerClass, ATxtDetailRecipientKey, AtxtDetailRecipientLedgerNumber, out AEnableRecipientGiftDestination); } }