private void ValidateDataManual(PmGeneralApplicationRow ARow)
        {
            TVerificationResultCollection VerificationResultCollection = FPetraUtilsObject.VerificationResultCollection;
            DataColumn ValidationColumn;
            TValidationControlsData ValidationControlsData;
            TVerificationResult     VerificationResult = null;

            TSharedPersonnelValidation_Personnel.ValidateGeneralApplicationManual(this, ARow, true, ref VerificationResultCollection,
                                                                                  FValidationControlsDict);

            TSharedPersonnelValidation_Personnel.ValidateEventApplicationManual(this,
                                                                                FMainDS.PmShortTermApplication[0],
                                                                                ref VerificationResultCollection,
                                                                                FValidationControlsDict);

            if (FDelegateCheckEventApplicationDuplicate != null)
            {
                // Same 'Event' must only exist for one application per person
                ValidationColumn = FMainDS.PmShortTermApplication[0].Table.Columns[PmShortTermApplicationTable.ColumnStConfirmedOptionId];

                if (FValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData))
                {
                    if (FDelegateCheckEventApplicationDuplicate(ARow.ApplicationKey, ARow.RegistrationOffice,
                                                                FMainDS.PmShortTermApplication[0].StConfirmedOption))
                    {
                        VerificationResult = new TScreenVerificationResult(new TVerificationResult(this,
                                                                                                   ErrorCodes.GetErrorInfo(PetraErrorCodes.ERR_APPLICATION_DUPLICATE_EVENT,
                                                                                                                           new string[] { FMainDS.PmShortTermApplication[0].StConfirmedOption.ToString() })),
                                                                           ValidationColumn, ValidationControlsData.ValidationControl);

                        // Handle addition to/removal from TVerificationResultCollection.
                        // Only add/remove verification result if duplicate found as same field has already been
                        // handled in TSharedPersonnelValidation_Personnel.ValidateEventApplicationManual
                        VerificationResultCollection.Auto_Add_Or_AddOrRemove(this, VerificationResult, ValidationColumn);
                    }
                }
            }
        }
        // The main validation method for the controls on this tab page
        private void ValidateDataManual(ALedgerRow ARow)
        {
            TVerificationResultCollection VerificationResultCollection = FPetraUtilsObject.VerificationResultCollection;
            DataColumn ValidationColumn;
            TValidationControlsData ValidationControlsData;
            TVerificationResult     VerificationResult = null;

            // make sure that Financial Year Start Date is no later than 28th of a month
            // (this field is not part of a_ledger but will be stored in period 1 of a_accounting_period)
            if (rbtMonthly.Checked)
            {
                // make sure that Financial Year Start Date is not empty
                // (this field is not part of a_ledger but will be stored in period 1 of a_accounting_period)
                if (dtpFinancialYearStartDate.Date == null)
                {
                    VerificationResult = new TScreenVerificationResult(
                        TDateChecks.IsNotUndefinedDateTime(
                            dtpFinancialYearStartDate.Date,
                            lblFinancialYearStartDate.Text.Trim(':'),
                            true,
                            this),
                        null,
                        dtpFinancialYearStartDate);
                }
                else if (dtpFinancialYearStartDate.Date.Value.Day > 28)
                {
                    VerificationResult = new TScreenVerificationResult(
                        this,
                        new DataColumn(),
                        ErrorCodes.GetErrorInfo(PetraErrorCodes.ERR_PERIOD_START_DAY_AFTER_28).ErrorMessageText,
                        PetraErrorCodes.ERR_PERIOD_START_DAY_AFTER_28,
                        dtpFinancialYearStartDate,
                        TResultSeverity.Resv_Critical);
                }
                else
                {
                    VerificationResult = null;
                }

                // Handle addition/removal to/from TVerificationResultCollection
                VerificationResultCollection.Auto_Add_Or_AddOrRemove(this, VerificationResult, null);
            }

            // check that there no suspense accounts for this ledger if box is unticked
            ValidationColumn = ARow.Table.Columns[ALedgerTable.ColumnSuspenseAccountFlagId];

            if (FValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData))
            {
                if (!ARow.SuspenseAccountFlag)
                {
                    if (TRemote.MFinance.Common.ServerLookups.WebConnectors.HasSuspenseAccounts(FLedgerNumber))
                    {
                        VerificationResult = new TScreenVerificationResult(new TVerificationResult(this,
                                                                                                   ErrorCodes.GetErrorInfo(PetraErrorCodes.ERR_NO_SUSPENSE_ACCOUNTS_ALLOWED)),
                                                                           ValidationColumn, ValidationControlsData.ValidationControl);
                    }
                    else
                    {
                        VerificationResult = null;
                    }

                    // Handle addition/removal to/from TVerificationResultCollection
                    VerificationResultCollection.Auto_Add_Or_AddOrRemove(this, VerificationResult, ValidationColumn);
                }
            }

            // check that the number of forwarding periods is not less than the already used ones
            ValidationColumn = ARow.Table.Columns[ALedgerTable.ColumnNumberFwdPostingPeriodsId];

            if (FValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData))
            {
                if (ARow.NumberFwdPostingPeriods < FMainForm.CurrentForwardPostingPeriods)
                {
                    VerificationResult = new TScreenVerificationResult(new TVerificationResult(this,
                                                                                               ErrorCodes.GetErrorInfo(PetraErrorCodes.ERR_NUMBER_FWD_PERIODS_TOO_SMALL,
                                                                                                                       new string[] { FMainForm.CurrentForwardPostingPeriods.ToString(), FMainForm.CurrentForwardPostingPeriods.ToString() })),
                                                                       ValidationColumn, ValidationControlsData.ValidationControl);
                }
                else
                {
                    VerificationResult = null;
                }

                // Handle addition/removal to/from TVerificationResultCollection
                VerificationResultCollection.Auto_Add_Or_AddOrRemove(this, VerificationResult, ValidationColumn);
            }

            // check that current period is not greater than number of ledger periods
            ValidationColumn = ARow.Table.Columns[ALedgerTable.ColumnNumberOfAccountingPeriodsId];

            if (FValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData))
            {
                if (ARow.CurrentPeriod > ARow.NumberOfAccountingPeriods)
                {
                    VerificationResult = new TScreenVerificationResult(new TVerificationResult(this,
                                                                                               ErrorCodes.GetErrorInfo(PetraErrorCodes.ERR_CURRENT_PERIOD_TOO_LATE)),
                                                                       ValidationColumn, ValidationControlsData.ValidationControl);
                }
                else
                {
                    VerificationResult = null;
                }

                // Handle addition/removal to/from TVerificationResultCollection
                VerificationResultCollection.Auto_Add_Or_AddOrRemove(this, VerificationResult, ValidationColumn);
            }
        }
        /// <summary>
        /// This is used to rearrnage the controls for when the Tax Deductibility Percentage is enabled (i.e. OM CH).
        /// It is unfortunately highly manual and might look confusing.
        /// But it seems to be the simpliest way to do this without writing a new screen specically for when this functionality is enabled.
        /// </summary>
        private void SetupTaxDeductibilityControls()
        {
            const int YSPACE  = 25;
            const int YSPACE2 = YSPACE * 2;

            /* move standard controls */
            lblDetailMailingCode.Location = new System.Drawing.Point(lblDetailMailingCode.Location.X, lblDetailMailingCode.Location.Y + (YSPACE * 2));
            cmbDetailMailingCode.Location = new System.Drawing.Point(cmbDetailMailingCode.Location.X, cmbDetailMailingCode.Location.Y + (YSPACE * 2));

            lblDetailAccountCode.Location = new System.Drawing.Point(lblDetailAccountCode.Location.X, lblDetailAccountCode.Location.Y + YSPACE2);
            txtDetailAccountCode.Location = new System.Drawing.Point(txtDetailAccountCode.Location.X, txtDetailAccountCode.Location.Y + YSPACE2);
            txtDetailAccountCode.Width    = 80;

            lblDetailGiftCommentOne.Location = new System.Drawing.Point(lblDetailGiftCommentOne.Location.X,
                                                                        lblDetailGiftCommentOne.Location.Y + YSPACE2);
            txtDetailGiftCommentOne.Location = new System.Drawing.Point(txtDetailGiftCommentOne.Location.X,
                                                                        txtDetailGiftCommentOne.Location.Y + YSPACE2);
            lblDetailCommentOneType.Location = new System.Drawing.Point(lblDetailCommentOneType.Location.X,
                                                                        lblDetailCommentOneType.Location.Y + YSPACE2);
            cmbDetailCommentOneType.Location = new System.Drawing.Point(cmbDetailCommentOneType.Location.X,
                                                                        cmbDetailCommentOneType.Location.Y + YSPACE2);
            lblDetailGiftCommentTwo.Location = new System.Drawing.Point(lblDetailGiftCommentTwo.Location.X,
                                                                        lblDetailGiftCommentTwo.Location.Y + YSPACE2);
            txtDetailGiftCommentTwo.Location = new System.Drawing.Point(txtDetailGiftCommentTwo.Location.X,
                                                                        txtDetailGiftCommentTwo.Location.Y + YSPACE2);
            lblDetailCommentTwoType.Location = new System.Drawing.Point(lblDetailCommentTwoType.Location.X,
                                                                        lblDetailCommentTwoType.Location.Y + YSPACE2);
            cmbDetailCommentTwoType.Location = new System.Drawing.Point(cmbDetailCommentTwoType.Location.X,
                                                                        cmbDetailCommentTwoType.Location.Y + YSPACE2);
            lblDetailGiftCommentThree.Location = new System.Drawing.Point(lblDetailGiftCommentThree.Location.X,
                                                                          lblDetailGiftCommentThree.Location.Y + YSPACE2);
            txtDetailGiftCommentThree.Location = new System.Drawing.Point(txtDetailGiftCommentThree.Location.X,
                                                                          txtDetailGiftCommentThree.Location.Y + YSPACE2);
            lblDetailCommentThreeType.Location = new System.Drawing.Point(lblDetailCommentThreeType.Location.X,
                                                                          lblDetailCommentThreeType.Location.Y + YSPACE2);
            cmbDetailCommentThreeType.Location = new System.Drawing.Point(cmbDetailCommentThreeType.Location.X,
                                                                          cmbDetailCommentThreeType.Location.Y + YSPACE2);

            grpDetailsForEachGift.Height += YSPACE2;

            // If pnlDetails is not big enough then move the splitter. Only want to move the splitter once as it's new location will be remembered.
            if (this.FindForm().Visible&& pnlDetails.VerticalScroll.Visible)
            {
                sptTransactions.SplitterDistance -= YSPACE2;
            }

            /* move tax deductibility controls and make them visible */
            lblDeductiblePercentage.Location =
                new System.Drawing.Point(lblDeductiblePercentage.Location.X, lblDeductiblePercentage.Location.Y - (YSPACE * 7));
            txtDeductiblePercentage.Location =
                new System.Drawing.Point(txtDeductiblePercentage.Location.X, txtDeductiblePercentage.Location.Y - (YSPACE * 7));
            lblDeductiblePercentage.Visible              = true;
            txtDeductiblePercentage.Visible              = true;
            txtDeductiblePercentage.NumberValueDecimal   = 100;
            txtDeductiblePercentage.NegativeValueAllowed = false;

            lblTaxDeductAmount.Location     = new System.Drawing.Point(lblTaxDeductAmount.Location.X - 5, lblTaxDeductAmount.Location.Y - (YSPACE * 5));
            lblTaxDeductAmount.Width        = lblTaxDeductAmount.Width + 10;
            txtTaxDeductAmount.Location     = new System.Drawing.Point(txtTaxDeductAmount.Location.X, txtTaxDeductAmount.Location.Y - (YSPACE * 5));
            lblTaxDeductAmount.Visible      = true;
            txtTaxDeductAmount.Visible      = true;
            txtTaxDeductAmount.CurrencyCode = FBatchRow.CurrencyCode;
            lblTaxDeductAmount.Text         = Catalog.GetString("Tax Deductible Amt:");
            lblNonDeductAmount.Location     = new System.Drawing.Point(lblNonDeductAmount.Location.X - 6, lblNonDeductAmount.Location.Y - (YSPACE * 3));
            lblNonDeductAmount.Width        = lblNonDeductAmount.Width + 11;
            txtNonDeductAmount.Location     = new System.Drawing.Point(txtNonDeductAmount.Location.X, txtNonDeductAmount.Location.Y - (YSPACE * 3));
            lblNonDeductAmount.Visible      = true;
            txtNonDeductAmount.Visible      = true;
            txtNonDeductAmount.CurrencyCode = FBatchRow.CurrencyCode;
            lblNonDeductAmount.Text         = Catalog.GetString("Non Deductible Amt:");

            lblDeductibleAccount.Location = new System.Drawing.Point(lblDeductibleAccount.Location.X, lblDeductibleAccount.Location.Y - (YSPACE * 5));
            txtDeductibleAccount.Location = new System.Drawing.Point(txtDeductibleAccount.Location.X, txtDeductibleAccount.Location.Y - (YSPACE * 5));
            lblDeductibleAccount.Visible  = true;
            txtDeductibleAccount.Visible  = true;
            txtDeductibleAccount.Width    = txtDetailAccountCode.Width;

            /* add event */
            txtDeductiblePercentage.TextChanged += UpdateTaxDeductibilityAmounts;

            /* add extra column to grid */
            grdDetails.AddTextColumn(Catalog.GetString("% Tax Deductibility"), FMainDS.AGiftDetail.ColumnTaxDeductiblePct);

            /* fix tab order */
            int STARTINGINDEX = txtDetailGiftTransactionAmount.TabIndex + 20;

            txtDeductiblePercentage.TabIndex       = STARTINGINDEX;
            txtTaxDeductAmount.TabIndex            = STARTINGINDEX += 20;
            txtNonDeductAmount.TabIndex            = STARTINGINDEX += 20;
            cmbDetailMotivationGroupCode.TabIndex  = STARTINGINDEX += 20;
            cmbDetailMotivationDetailCode.TabIndex = STARTINGINDEX += 20;
            cmbDetailMailingCode.TabIndex          = STARTINGINDEX += 20;
            txtDetailCostCentreCode.TabIndex       = STARTINGINDEX += 20;
            txtDeductibleAccount.TabIndex          = STARTINGINDEX += 20;
            txtDetailAccountCode.TabIndex          = STARTINGINDEX += 20;
            txtDetailGiftCommentOne.TabIndex       = STARTINGINDEX += 20;
            cmbDetailCommentOneType.TabIndex       = STARTINGINDEX += 20;
            txtDetailGiftCommentTwo.TabIndex       = STARTINGINDEX += 20;
            cmbDetailCommentTwoType.TabIndex       = STARTINGINDEX += 20;
            txtDetailGiftCommentThree.TabIndex     = STARTINGINDEX += 20;
            cmbDetailCommentThreeType.TabIndex     = STARTINGINDEX += 20;

            if (FMainDS.AGiftDetail != null)
            {
                FValidationControlsDict.Add(FMainDS.AGiftDetail.Columns[(short)FMainDS.AGiftDetail.GetType().GetField("ColumnTaxDeductiblePctId",
                                                                                                                      BindingFlags.Public | BindingFlags.Static |
                                                                                                                      BindingFlags.FlattenHierarchy).GetValue(FMainDS.AGiftDetail.GetType())],
                                            new TValidationControlsData(txtDeductiblePercentage, Catalog.GetString("% Tax Deductible")));
            }
        }