Example #1
0
        /// <summary>
        /// Looks for gifts where the donor is anoymous but the gift is not marked as confidential and asks the user if they want to continue.
        /// (Make sure GetDataFromControls is called before this method so that AMainDS is up-to-date.)
        /// </summary>
        /// <param name="AMainDS"></param>
        public static bool CanContinueWithAnyAnonymousDonors(GiftBatchTDS AMainDS)
        {
            GiftBatchTDSAGiftDetailTable UnConfidentialGiftsWithAnonymousDonors = new GiftBatchTDSAGiftDetailTable();

            foreach (GiftBatchTDSAGiftDetailRow Row in AMainDS.AGiftDetail.Rows)
            {
                if (!Row.ConfidentialGiftFlag)
                {
                    PPartnerRow PartnerRow = (PPartnerRow)AMainDS.DonorPartners.Rows.Find(Row.DonorKey);

                    if ((PartnerRow != null) && PartnerRow.AnonymousDonor)
                    {
                        UnConfidentialGiftsWithAnonymousDonors.Rows.Add((object[])Row.ItemArray.Clone());
                    }
                }
            }

            if (UnConfidentialGiftsWithAnonymousDonors.Rows.Count > 0)
            {
                string Message = string.Empty;

                DataView dv = UnConfidentialGiftsWithAnonymousDonors.DefaultView;
                dv.Sort = GiftBatchTDSAGiftDetailTable.GetGiftTransactionNumberDBName() + " ASC";
                DataTable sortedDT = dv.ToTable();

                if (UnConfidentialGiftsWithAnonymousDonors.Rows.Count == 1)
                {
                    Message = Catalog.GetString(
                        "The gift listed below in this batch is not marked as confidential but the donor has asked to remain anonymous.");
                }
                else
                {
                    Message = Catalog.GetString(
                        "The gifts listed below in this batch are not marked as confidential but the donors have asked to remain anonymous.");
                }

                Message += "\n\n";

                foreach (DataRow UnConfidentialGifts in sortedDT.Rows)
                {
                    Message += Catalog.GetString("Batch: ") + UnConfidentialGifts[GiftBatchTDSAGiftDetailTable.GetBatchNumberDBName()] + "; " +
                               Catalog.GetString("Gift: ") + UnConfidentialGifts[GiftBatchTDSAGiftDetailTable.GetGiftTransactionNumberDBName()] +
                               "; " +
                               Catalog.GetString("Donor: ") + UnConfidentialGifts[GiftBatchTDSAGiftDetailTable.GetDonorNameDBName()] + " (" +
                               UnConfidentialGifts[GiftBatchTDSAGiftDetailTable.GetDonorKeyDBName()] + ")\n";
                }

                Message += "\n" + Catalog.GetString("Do you want to continue with posting anyway?");

                if (MessageBox.Show(
                        Message, Catalog.GetString("Anonymous Donor Warning"), MessageBoxButtons.YesNo, MessageBoxIcon.Warning)
                    == DialogResult.No)
                {
                    return(false);
                }
            }

            return(true);
        }
Example #2
0
        public void SpeedTestLoadIntoTypedTable()
        {
            TDBTransaction ReadTransaction = null;
            DateTime       before          = DateTime.Now;
            DateTime       after           = DateTime.Now;
            GiftBatchTDS   ds = new GiftBatchTDS();

            DBAccess.GDBAccessObj.GetNewOrExistingAutoReadTransaction(
                IsolationLevel.ReadCommitted,
                TEnforceIsolationLevel.eilMinimum,
                ref ReadTransaction,
                delegate
            {
                string sql = "SELECT PUB_a_gift_detail.*, false AS AlreadyMatched, PUB_a_gift_batch.a_batch_status_c AS BatchStatus " +
                             "FROM PUB_a_gift_batch, PUB_a_gift_detail " +
                             "WHERE PUB_a_gift_detail.a_ledger_number_i = PUB_a_gift_batch.a_ledger_number_i AND PUB_a_gift_detail.a_batch_number_i = PUB_a_gift_batch.a_batch_number_i";

                before            = DateTime.Now;
                DataTable untyped = DBAccess.GDBAccessObj.SelectDT(sql, "test", ReadTransaction);
                after             = DateTime.Now;

                TLogging.Log(String.Format("loading all {0} gift details into an untyped table took {1} milliseconds",
                                           untyped.Rows.Count,
                                           (after.Subtract(before)).TotalMilliseconds));

                GiftBatchTDSAGiftDetailTable typed = new GiftBatchTDSAGiftDetailTable();
                before = DateTime.Now;
                DBAccess.GDBAccessObj.SelectDT(typed, sql, ReadTransaction, new OdbcParameter[0], 0, 0);
                after = DateTime.Now;

                TLogging.Log(String.Format("loading all {0} gift details into a typed table took {1} milliseconds",
                                           typed.Rows.Count,
                                           (after.Subtract(before)).TotalMilliseconds));

                AMotivationDetailAccess.LoadAll(ds, ReadTransaction);

                before = DateTime.Now;
                DBAccess.GDBAccessObj.Select(ds, sql, ds.AGiftDetail.TableName, ReadTransaction);
                after = DateTime.Now;
            });

            TLogging.Log(String.Format("loading all {0} gift details into a typed dataset took {1} milliseconds",
                                       ds.AGiftDetail.Rows.Count,
                                       (after.Subtract(before)).TotalMilliseconds));

            before = DateTime.Now;
            GiftBatchTDS ds2 = new GiftBatchTDS();

            ds2.Merge(ds.AGiftDetail);
            after = DateTime.Now;

            TLogging.Log(String.Format("merging typed table into other dataset took {0} milliseconds",
                                       (after.Subtract(before)).TotalMilliseconds));
        }
Example #3
0
        private static string GetExWorkersString(GiftBatchAction?AAction, string AExWorkerSpecialType, DataTable AExWorkers)
        {
            string ReturnValue = string.Empty;

            if (AExWorkers.Rows.Count == 0)
            {
                return(ReturnValue);
            }

            DataView dv = AExWorkers.DefaultView;

            dv.Sort = GiftBatchTDSAGiftDetailTable.GetGiftTransactionNumberDBName() + " ASC";
            DataTable sortedDT = dv.ToTable();

            if ((AAction == GiftBatchAction.POSTING) || (AAction == GiftBatchAction.SUBMITTING))
            {
                if (AExWorkers.Rows.Count == 1)
                {
                    ReturnValue = string.Format(Catalog.GetString(
                                                    "The gift listed below has a recipient who has a Special Type beginning with {0}:"), AExWorkerSpecialType);
                }
                else
                {
                    ReturnValue = string.Format(Catalog.GetString(
                                                    "The gifts listed below have recipients who have a Special Type beginning with {0}:"),
                                                AExWorkerSpecialType);
                }
            }
            else
            {
                if (AExWorkers.Rows.Count == 1)
                {
                    ReturnValue = string.Format(Catalog.GetString(
                                                    "The unsaved gift listed below is for a recipient who has Special Type beginning with {0}:"), AExWorkerSpecialType);
                }
                else
                {
                    ReturnValue = string.Format(Catalog.GetString(
                                                    "The unsaved gifts listed below are for recipients who have Special Type beginning with {0}:"), AExWorkerSpecialType);
                }
            }

            ReturnValue += "\n\n";

            foreach (DataRow Row in sortedDT.Rows)
            {
                ReturnValue += Catalog.GetString("Batch: ") + Row[GiftBatchTDSAGiftDetailTable.GetBatchNumberDBName()] + "; " +
                               Catalog.GetString("Gift: ") + Row[GiftBatchTDSAGiftDetailTable.GetGiftTransactionNumberDBName()] + "; " +
                               Catalog.GetString("Recipient: ") + Row[GiftBatchTDSAGiftDetailTable.GetRecipientDescriptionDBName()] + " (" +
                               Row[GiftBatchTDSAGiftDetailTable.GetRecipientKeyDBName()] + ")\n";
            }

            return(ReturnValue += "\n");
        }
Example #4
0
        /// <summary>
        /// Wrapper method to handle returned bool value from remoting call to ImportGiftBatches
        /// </summary>
        /// <param name="ARequestParams"></param>
        /// <param name="AImportString"></param>
        /// <param name="AMessages"></param>
        /// <param name="ok"></param>
        /// <param name="AGUIRefreshRequired"></param>
        /// <param name="ANeedRecipientLedgerNumber"></param>
        private void ImportGiftBatches(Hashtable ARequestParams, string AImportString, out TVerificationResultCollection AMessages,
                                       out bool ok, out bool AGUIRefreshRequired, out GiftBatchTDSAGiftDetailTable ANeedRecipientLedgerNumber)
        {
            TVerificationResultCollection AResultMessages;
            bool ImportIsSuccessful;

            ImportIsSuccessful = TRemote.MFinance.Gift.WebConnectors.ImportGiftBatches(
                ARequestParams,
                AImportString,
                out ANeedRecipientLedgerNumber,
                out AGUIRefreshRequired,
                out AResultMessages);

            ok        = ImportIsSuccessful;
            AMessages = AResultMessages;
        }
Example #5
0
        private static string GetExWorkersString(GiftBatchAction?AAction, string AExWorkerSpecialType, DataTable AExWorkers)
        {
            string ReturnValue = string.Empty;

            if (AExWorkers.Rows.Count == 0)
            {
                return(ReturnValue);
            }

            DataView dv = AExWorkers.DefaultView;

            dv.Sort = string.Format("{0} ASC, {1} ASC",
                                    GiftBatchTDSAGiftDetailTable.GetGiftTransactionNumberDBName(),
                                    GiftBatchTDSAGiftDetailTable.GetDetailNumberDBName());
            DataTable sortedDT = dv.ToTable();

            ReturnValue =
                String.Format(Catalog.GetString("The {0}gift(s) listed below have recipient(s) with a Special Type beginning with {1}:{2}{2}"),
                              ((AAction == GiftBatchAction.POSTING) || (AAction == GiftBatchAction.SUBMITTING)) ? "" : "unsaved ",
                              AExWorkerSpecialType,
                              Environment.NewLine);

            ReturnValue += new String('-', 86) + Environment.NewLine;

            foreach (DataRow Row in sortedDT.Rows)
            {
                ReturnValue += Catalog.GetString("Batch: ") + Row[GiftBatchTDSAGiftDetailTable.GetBatchNumberDBName()] + "; " +
                               Catalog.GetString("Gift: ") + Row[GiftBatchTDSAGiftDetailTable.GetGiftTransactionNumberDBName()] + "; " +
                               Catalog.GetString("Detail: ") + Row[GiftBatchTDSAGiftDetailTable.GetDetailNumberDBName()] + "; " +
                               Catalog.GetString("Recipient: ") + Row[GiftBatchTDSAGiftDetailTable.GetRecipientDescriptionDBName()] + " (" +
                               Row[GiftBatchTDSAGiftDetailTable.GetRecipientKeyDBName()] + ")" +
                               Environment.NewLine;
            }

            ReturnValue += new String('-', 86);

            return(ReturnValue);
        }
Example #6
0
        /// <summary>
        /// this supports the batch export files from Petra 2.x.
        /// Each line starts with a type specifier, B for batch, J for journal, T for transaction
        /// </summary>
        public void ImportBatches(TGiftImportDataSourceEnum AImportSource)
        {
            bool           ok = false;
            String         importString;
            String         impOptions;
            OpenFileDialog dialog = null;

            if (FPetraUtilsObject.HasChanges)
            {
                // saving failed, therefore do not try to post
                MessageBox.Show(Catalog.GetString("Please save before calling this function!"), Catalog.GetString(
                                    "Failure"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            FdlgSeparator = new TDlgSelectCSVSeparator(false);

            if (AImportSource == TGiftImportDataSourceEnum.FromClipboard)
            {
                importString = Clipboard.GetText(TextDataFormat.UnicodeText);

                if ((importString == null) || (importString.Length == 0))
                {
                    MessageBox.Show(Catalog.GetString("Please first copy data from your spreadsheet application!"),
                                    Catalog.GetString("Failure"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                impOptions = TUserDefaults.GetStringDefault("Imp Options", ";American");
                String dateFormatString = TUserDefaults.GetStringDefault("Imp Date", "MDY");
                FdlgSeparator = new TDlgSelectCSVSeparator(false);
                FdlgSeparator.SelectedSeparator = "\t";
                FdlgSeparator.CSVData           = importString;
                FdlgSeparator.DateFormat        = dateFormatString;

                if (impOptions.Length > 1)
                {
                    FdlgSeparator.NumberFormat = impOptions.Substring(1);
                }
            }
            else if (AImportSource == TGiftImportDataSourceEnum.FromFile)
            {
                dialog = new OpenFileDialog();

                string exportPath = TClientSettings.GetExportPath();
                string fullPath   = TUserDefaults.GetStringDefault("Imp Filename",
                                                                   exportPath + Path.DirectorySeparatorChar + "import.csv");
                TImportExportDialogs.SetOpenFileDialogFilePathAndName(dialog, fullPath, exportPath);

                dialog.Title  = Catalog.GetString("Import Batches from CSV File");
                dialog.Filter = Catalog.GetString("Gift Batches files (*.csv)|*.csv");
                impOptions    = TUserDefaults.GetStringDefault("Imp Options", ";" + TDlgSelectCSVSeparator.NUMBERFORMAT_AMERICAN);

                // This call fixes Windows7 Open File Dialogs.  It must be the line before ShowDialog()
                TWin7FileOpenSaveDialog.PrepareDialog(Path.GetFileName(fullPath));

                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    Boolean fileCanOpen = FdlgSeparator.OpenCsvFile(dialog.FileName);

                    if (!fileCanOpen)
                    {
                        MessageBox.Show(Catalog.GetString("Unable to open file."),
                                        Catalog.GetString("Gift Import"),
                                        MessageBoxButtons.OK,
                                        MessageBoxIcon.Stop);
                        return;
                    }

                    importString = File.ReadAllText(dialog.FileName, Encoding.Default);

                    String dateFormatString = TUserDefaults.GetStringDefault("Imp Date", "MDY");
                    FdlgSeparator.DateFormat = dateFormatString;

                    if (impOptions.Length > 1)
                    {
                        FdlgSeparator.NumberFormat = impOptions.Substring(1);
                    }

                    FdlgSeparator.SelectedSeparator = impOptions.Substring(0, 1);
                }
                else
                {
                    return;
                }
            }
            else
            {
                // unknown source!!  The following need a value...
                impOptions   = String.Empty;
                importString = String.Empty;
            }

            if (FdlgSeparator.ShowDialog() == DialogResult.OK)
            {
                Hashtable requestParams = new Hashtable();

                requestParams.Add("ALedgerNumber", FLedgerNumber);
                requestParams.Add("Delimiter", FdlgSeparator.SelectedSeparator);
                requestParams.Add("DateFormatString", FdlgSeparator.DateFormat);
                requestParams.Add("NumberFormat", FdlgSeparator.NumberFormat);
                requestParams.Add("NewLine", Environment.NewLine);

                bool Repeat = true;

                while (Repeat)
                {
                    Repeat = false;

                    TVerificationResultCollection AMessages = new TVerificationResultCollection();
                    GiftBatchTDSAGiftDetailTable  NeedRecipientLedgerNumber = new GiftBatchTDSAGiftDetailTable();

                    Thread ImportThread = new Thread(() => ImportGiftBatches(
                                                         requestParams,
                                                         importString,
                                                         out AMessages,
                                                         out ok,
                                                         out NeedRecipientLedgerNumber));

                    using (TProgressDialog ImportDialog = new TProgressDialog(ImportThread))
                    {
                        ImportDialog.ShowDialog();
                    }

                    // If NeedRecipientLedgerNumber contains data then AMessages will only ever contain
                    // one message alerting the user that no data has been imported.
                    // We do not want to show this as we will be displaying another more detailed message.
                    if (NeedRecipientLedgerNumber.Rows.Count == 0)
                    {
                        ShowMessages(AMessages);
                    }

                    // if the import contains gifts with Motivation Group 'GIFT' and that have a Family recipient with no Gift Destination
                    // then the import will have failed and we need to alert the user
                    if (NeedRecipientLedgerNumber.Rows.Count > 0)
                    {
                        bool OfferToRunImportAgain            = true;
                        bool DoNotShowMessageBoxEverytime     = false;
                        TFrmExtendedMessageBox.TResult Result = TFrmExtendedMessageBox.TResult.embrUndefined;
                        int count = 1;

                        // for each gift in which the recipient needs a Git Destination
                        foreach (GiftBatchTDSAGiftDetailRow Row in NeedRecipientLedgerNumber.Rows)
                        {
                            if (!DoNotShowMessageBoxEverytime)
                            {
                                string CheckboxText = string.Empty;

                                // only show checkbox if there is at least one more occurance of this error
                                if (NeedRecipientLedgerNumber.Rows.Count - count > 0)
                                {
                                    CheckboxText = string.Format(
                                        Catalog.GetString("Do this for all further occurances ({0})?"), NeedRecipientLedgerNumber.Rows.Count - count);
                                }

                                TFrmExtendedMessageBox extendedMessageBox = new TFrmExtendedMessageBox(FPetraUtilsObject.GetForm());

                                extendedMessageBox.ShowDialog(string.Format(
                                                                  Catalog.GetString(
                                                                      "Gift Import has been cancelled as the recipient '{0}' ({1}) has no Gift Destination assigned."),
                                                                  Row.RecipientDescription, Row.RecipientKey) +
                                                              "\n\r\n\r\n\r" +
                                                              Catalog.GetString("Do you want to assign a Gift Destination to this partner now?"),
                                                              Catalog.GetString("Import Errors"),
                                                              CheckboxText,
                                                              TFrmExtendedMessageBox.TButtons.embbYesNo, TFrmExtendedMessageBox.TIcon.embiWarning);
                                Result = extendedMessageBox.GetResult(out DoNotShowMessageBoxEverytime);
                            }

                            if (Result == TFrmExtendedMessageBox.TResult.embrYes)
                            {
                                // allow the user to assign a Gift Destingation
                                TFrmGiftDestination GiftDestinationForm = new TFrmGiftDestination(FPetraUtilsObject.GetForm(), Row.RecipientKey);
                                GiftDestinationForm.ShowDialog();
                            }
                            else
                            {
                                OfferToRunImportAgain = false;

                                if (DoNotShowMessageBoxEverytime)
                                {
                                    break;
                                }
                            }

                            count++;
                        }

                        // if the user has clicked yes to assigning Gift Destinations then offer to restart the import
                        if (OfferToRunImportAgain &&
                            (MessageBox.Show(Catalog.GetString("Would you like to import this Gift Batch again?"),
                                             Catalog.GetString("Gift Import"), MessageBoxButtons.YesNo, MessageBoxIcon.Question,
                                             MessageBoxDefaultButton.Button2)
                             == DialogResult.Yes))
                        {
                            Repeat = true;
                        }
                    }
                }

                // We save the defaults even if ok is false - because the client will probably want to try and import
                //   the same file again after correcting any errors
                SaveUserDefaults(dialog, impOptions);
            }

            if (ok)
            {
                MessageBox.Show(Catalog.GetString("Your data was imported successfully!"),
                                Catalog.GetString("Gift Import"),
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);

                FMyUserControl.LoadBatchesForCurrentYear();
                FPetraUtilsObject.DisableSaveButton();
            }
        }
        private void FPetraUtilsObject_DataSavingStarted_NewDonorWarning()
        {
            GetDataFromControls();

            FGiftDetailTable = FMainDS.AGiftDetail.GetChangesTyped();
        }
        /// <summary>
        /// Main method to post a specified batch
        /// </summary>
        /// <param name="ACurrentBatchRow">The batch row to post</param>
        /// <param name="APostingAlreadyConfirmed">True means ask user if they want to post</param>
        /// <param name="AWarnOfInactiveValues">True means user is warned if inactive values exist</param>
        /// <param name="ADonorZeroIsValid"></param>
        /// <param name="ARecipientZeroIsValid"></param>
        /// <returns>True if the batch was successfully posted</returns>
        public bool PostBatch(AGiftBatchRow ACurrentBatchRow,
                              bool APostingAlreadyConfirmed = false,
                              bool AWarnOfInactiveValues    = true,
                              bool ADonorZeroIsValid        = false,
                              bool ARecipientZeroIsValid    = false)
        {
            //This assumes that all gift data etc is loaded into the batch before arriving here

            bool RetVal = false;

            if ((ACurrentBatchRow == null) || (ACurrentBatchRow.BatchStatus != MFinanceConstants.BATCH_UNPOSTED))
            {
                return(RetVal);
            }

            FSelectedBatchNumber = ACurrentBatchRow.BatchNumber;
            TVerificationResultCollection Verifications;

            try
            {
                //Make sure that all control data is in dataset
                FMyForm.GetControlDataForPosting();

                GiftBatchTDSAGiftDetailTable batchGiftDetails = new GiftBatchTDSAGiftDetailTable();
                DataView batchGiftDetailsDV = new DataView(FMainDS.AGiftDetail);

                batchGiftDetailsDV.RowFilter = string.Format("{0}={1}",
                                                             AGiftDetailTable.GetBatchNumberDBName(),
                                                             FSelectedBatchNumber);

                batchGiftDetailsDV.Sort = string.Format("{0} ASC, {1} ASC, {2} ASC",
                                                        AGiftDetailTable.GetBatchNumberDBName(),
                                                        AGiftDetailTable.GetGiftTransactionNumberDBName(),
                                                        AGiftDetailTable.GetDetailNumberDBName());

                foreach (DataRowView drv in batchGiftDetailsDV)
                {
                    GiftBatchTDSAGiftDetailRow gBRow = (GiftBatchTDSAGiftDetailRow)drv.Row;

                    batchGiftDetails.Rows.Add((object[])gBRow.ItemArray.Clone());
                }

                bool CancelledDueToExWorkerOrAnonDonor;

                // save first, then post
                if (!FMyForm.SaveChangesForPosting(batchGiftDetails, out CancelledDueToExWorkerOrAnonDonor))
                {
                    FMyForm.Cursor = Cursors.Default;

                    if (!CancelledDueToExWorkerOrAnonDonor)
                    {
                        // saving failed, therefore do not try to post
                        MessageBox.Show(Catalog.GetString("The batch was not posted due to problems during saving; ") + Environment.NewLine +
                                        Catalog.GetString("Please first correct and save the batch, and then post it!"));
                    }

                    return(RetVal);
                }
            }
            catch (Exception ex)
            {
                TLogging.LogException(ex, Utilities.GetMethodSignature());
                throw;
            }

            //Check for missing international exchange rate
            bool IsTransactionInIntlCurrency = false;

            FMyForm.WarnAboutMissingIntlExchangeRate = true;

            if (FMyForm.InternationalCurrencyExchangeRate(ACurrentBatchRow, out IsTransactionInIntlCurrency, true) == 0)
            {
                return(RetVal);
            }

            //Check for zero Donors or Recipients
            if (!ADonorZeroIsValid)
            {
                DataView batchGiftDV = new DataView(FMainDS.AGift);

                batchGiftDV.RowFilter = string.Format("{0}={1} And {2}=0",
                                                      AGiftTable.GetBatchNumberDBName(),
                                                      FSelectedBatchNumber,
                                                      AGiftTable.GetDonorKeyDBName());

                int numDonorZeros = batchGiftDV.Count;

                if (numDonorZeros > 0)
                {
                    string messageListOfOffendingGifts =
                        String.Format(Catalog.GetString(
                                          "Gift Batch {0} contains {1} gift detail(s) with Donor 0000000. Please fix before posting!{2}{2}"),
                                      FSelectedBatchNumber,
                                      numDonorZeros,
                                      Environment.NewLine);

                    string listOfOffendingRows = string.Empty;

                    listOfOffendingRows += "Gift" + Environment.NewLine;
                    listOfOffendingRows += "------------";

                    foreach (DataRowView drv in batchGiftDV)
                    {
                        AGiftRow giftRow = (AGiftRow)drv.Row;

                        listOfOffendingRows += String.Format("{0}{1:0000}",
                                                             Environment.NewLine,
                                                             giftRow.GiftTransactionNumber);
                    }

                    TFrmExtendedMessageBox extendedMessageBox = new TFrmExtendedMessageBox(FMyForm);

                    extendedMessageBox.ShowDialog((messageListOfOffendingGifts + listOfOffendingRows),
                                                  Catalog.GetString("Post Batch Error"), string.Empty,
                                                  TFrmExtendedMessageBox.TButtons.embbOK,
                                                  TFrmExtendedMessageBox.TIcon.embiWarning);

                    return(RetVal);
                }
            }

            if (!ARecipientZeroIsValid)
            {
                DataView batchGiftDetailsDV = new DataView(FMainDS.AGiftDetail);

                batchGiftDetailsDV.RowFilter = string.Format("{0}={1} And {2}=0",
                                                             AGiftDetailTable.GetBatchNumberDBName(),
                                                             FSelectedBatchNumber,
                                                             AGiftDetailTable.GetRecipientKeyDBName());

                int numRecipientZeros = batchGiftDetailsDV.Count;

                if (numRecipientZeros > 0)
                {
                    string messageListOfOffendingGifts =
                        String.Format(Catalog.GetString(
                                          "Gift Batch {0} contains {1} gift detail(s) with Recipient 0000000. Please fix before posting!{2}{2}"),
                                      FSelectedBatchNumber,
                                      numRecipientZeros,
                                      Environment.NewLine);

                    string listOfOffendingRows = string.Empty;

                    listOfOffendingRows += "Gift   Detail" + Environment.NewLine;
                    listOfOffendingRows += "-------------------";

                    foreach (DataRowView drv in batchGiftDetailsDV)
                    {
                        AGiftDetailRow giftDetailRow = (AGiftDetailRow)drv.Row;

                        listOfOffendingRows += String.Format("{0}{1:0000}  {2:00}",
                                                             Environment.NewLine,
                                                             giftDetailRow.GiftTransactionNumber,
                                                             giftDetailRow.DetailNumber);
                    }

                    TFrmExtendedMessageBox extendedMessageBox = new TFrmExtendedMessageBox(FMyForm);

                    extendedMessageBox.ShowDialog((messageListOfOffendingGifts + listOfOffendingRows),
                                                  Catalog.GetString("Post Batch Error"), string.Empty,
                                                  TFrmExtendedMessageBox.TButtons.embbOK,
                                                  TFrmExtendedMessageBox.TIcon.embiWarning);

                    return(RetVal);
                }
            }

            //Check for inactive KeyMinistries
            DataTable GiftsWithInactiveKeyMinistries;
            bool      ModifiedDetails = false;

            if (AWarnOfInactiveValues && TRemote.MFinance.Gift.WebConnectors.InactiveKeyMinistriesFoundInBatch(FLedgerNumber, FSelectedBatchNumber,
                                                                                                               out GiftsWithInactiveKeyMinistries, false))
            {
                int numInactiveValues = GiftsWithInactiveKeyMinistries.Rows.Count;

                string messageNonModifiedBatch =
                    String.Format(Catalog.GetString("Gift Batch {0} contains {1} inactive key ministries. Please fix before posting!{2}{2}"),
                                  FSelectedBatchNumber,
                                  numInactiveValues,
                                  Environment.NewLine);
                string messageModifiedBatch =
                    String.Format(Catalog.GetString(
                                      "Reversal/Adjustment Gift Batch {0} contains {1} inactive key ministries. Do you still want to post?{2}{2}"),
                                  FSelectedBatchNumber,
                                  numInactiveValues,
                                  Environment.NewLine);

                string listOfOffendingRows = string.Empty;

                listOfOffendingRows += "Gift      Detail   Recipient          KeyMinistry" + Environment.NewLine;
                listOfOffendingRows += "-------------------------------------------------------------------------------";

                foreach (DataRow dr in GiftsWithInactiveKeyMinistries.Rows)
                {
                    listOfOffendingRows += String.Format("{0}{1:0000}    {2:00}        {3:00000000000}    {4}",
                                                         Environment.NewLine,
                                                         dr[0],
                                                         dr[1],
                                                         dr[2],
                                                         dr[3]);

                    bool isModified = Convert.ToBoolean(dr[4]);

                    if (isModified)
                    {
                        ModifiedDetails = true;
                    }
                }

                TFrmExtendedMessageBox extendedMessageBox = new TFrmExtendedMessageBox(FMyForm);

                if (ModifiedDetails)
                {
                    if (extendedMessageBox.ShowDialog((messageModifiedBatch + listOfOffendingRows),
                                                      Catalog.GetString("Post Batch"), string.Empty,
                                                      TFrmExtendedMessageBox.TButtons.embbYesNo,
                                                      TFrmExtendedMessageBox.TIcon.embiWarning) == TFrmExtendedMessageBox.TResult.embrYes)
                    {
                        APostingAlreadyConfirmed = true;
                    }
                    else
                    {
                        return(RetVal);
                    }
                }
                else
                {
                    extendedMessageBox.ShowDialog((messageNonModifiedBatch + listOfOffendingRows),
                                                  Catalog.GetString("Post Batch Error"), string.Empty,
                                                  TFrmExtendedMessageBox.TButtons.embbOK,
                                                  TFrmExtendedMessageBox.TIcon.embiWarning);

                    return(RetVal);
                }
            }

            // ask if the user really wants to post the batch
            if (!APostingAlreadyConfirmed &&
                (MessageBox.Show(String.Format(Catalog.GetString("Do you really want to post gift batch {0}?"), FSelectedBatchNumber),
                                 Catalog.GetString("Confirm posting of Gift Batch"),
                                 MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes))
            {
                return(RetVal);
            }

            Verifications = new TVerificationResultCollection();

            try
            {
                FPostingInProgress = true;

                Thread postingThread = new Thread(() => PostGiftBatch(out Verifications));

                using (TProgressDialog dialog = new TProgressDialog(postingThread))
                {
                    dialog.ShowDialog();
                }

                if (!TVerificationHelper.IsNullOrOnlyNonCritical(Verifications))
                {
                    TFrmExtendedMessageBox extendedMessageBox = new TFrmExtendedMessageBox(FMyForm);

                    StringBuilder errorMessages = new StringBuilder();
                    int           counter       = 0;

                    errorMessages.AppendLine(Catalog.GetString("________________________Gift Posting Errors________________________"));
                    errorMessages.AppendLine();

                    foreach (TVerificationResult verif in Verifications)
                    {
                        counter++;
                        errorMessages.AppendLine(counter.ToString("000") + " - " + verif.ResultText);
                        errorMessages.AppendLine();
                    }

                    extendedMessageBox.ShowDialog(errorMessages.ToString(),
                                                  Catalog.GetString("Post Batch Error"),
                                                  string.Empty,
                                                  TFrmExtendedMessageBox.TButtons.embbOK,
                                                  TFrmExtendedMessageBox.TIcon.embiWarning);
                }
                else
                {
                    MessageBox.Show(Catalog.GetString("The batch has been posted successfully!"));

                    RetVal = true;
                }
            }
            catch (Exception ex)
            {
                TLogging.LogException(ex, Utilities.GetMethodSignature());
                throw;
            }
            finally
            {
                FPostingInProgress = false;
            }

            return(RetVal);
        }
Example #9
0
        public static bool ImportGiftTransactions(
            Hashtable requestParams,
            String importString,
            Int32 AGiftBatchNumber,
            out GiftBatchTDSAGiftDetailTable ANeedRecipientLedgerNumber,
            out TVerificationResultCollection AMessages
            )
        {
            TGiftImporting Importing = new TGiftImporting();

            return Importing.ImportGiftTransactions(requestParams, importString, AGiftBatchNumber, out ANeedRecipientLedgerNumber, out AMessages);
        }
Example #10
0
        private void ParseTransactionLine(AGiftRow AGift,
            AGiftBatchRow AGiftBatch,
            ref AGiftRow APreviousGift,
            int ANumberOfColumns,
            ref decimal ATotalBatchAmount,
            ref string AImportMessage,
            int ARowNumber,
            decimal AIntlRateFromBase,
            TVerificationResultCollection AMessages,
            AMotivationDetailTable AMotivationDetailTable,
//            TValidationControlsDict AValidationControlsDictGift,
//            TValidationControlsDict AValidationControlsDictGiftDetail,
//            ACostCentreTable AValidationCostCentreTable,
//            AAccountTable AValidationAccountTable,
//            AMotivationGroupTable AValidationMotivationGroupTable,
//            AMethodOfGivingTable AValidationMethodOfGivingTable,
//            AMethodOfPaymentTable AValidationMethodOfPaymentTable,
//            PMailingTable AValidationMailingTable,
            GiftBatchTDSAGiftDetailTable ANeedRecipientLedgerNumber,
            AGiftDetailRow AGiftDetails)
        {
            // Start parsing
            int preParseMessageCount = AMessages.Count;

            // Is this the format with extra columns?
            // Actually if it has the extra columns but does not have the optional final 8 columns we cannot distiguish using this test...
            //   A file without extra columns will have between 13 and 21 columns - depending on whether some of the optional ones at the end are included.
            //   A file with extra columns will be between 19 and 27.
            //  So any count between 19 and 21 is ambiguous.  We will assume that if the file has extra columns it also has
            //   at least enough of the optional ones to exceed 21.
            bool HasExtraColumns = (ANumberOfColumns > 21);

            AImportMessage = Catalog.GetString("Importing the gift data");

            AGift.DonorKey = TCommonImport.ImportInt64(ref FImportLine, FDelimiter, Catalog.GetString("Donor key"),
                FMainDS.AGift.ColumnDonorKey, ARowNumber, AMessages, null);

            TCommonImport.ImportString(ref FImportLine, FDelimiter, Catalog.GetString(
                    "short name of donor (unused)"), null, ARowNumber, AMessages, null);                                                                   // unused

            // This group is optional and database NULL's are allowed
            AGift.MethodOfGivingCode = TCommonImport.ImportString(ref FImportLine, FDelimiter, Catalog.GetString("Method of giving Code"),
                FMainDS.AGift.ColumnMethodOfGivingCode, ARowNumber, AMessages, null, false);
            AGift.MethodOfPaymentCode = TCommonImport.ImportString(ref FImportLine, FDelimiter, Catalog.GetString("Method Of Payment Code"),
                FMainDS.AGift.ColumnMethodOfPaymentCode, ARowNumber, AMessages, null, false);
            AGift.Reference = TCommonImport.ImportString(ref FImportLine, FDelimiter, Catalog.GetString("Reference"),
                FMainDS.AGift.ColumnReference, ARowNumber, AMessages, null, false);
            AGift.ReceiptLetterCode = TCommonImport.ImportString(ref FImportLine, FDelimiter, Catalog.GetString("Receipt letter code"),
                FMainDS.AGift.ColumnReceiptLetterCode, ARowNumber, AMessages, null, false);

            if (AGift.MethodOfGivingCode != null)
            {
                AGift.MethodOfGivingCode = AGift.MethodOfGivingCode.ToUpper();
            }

            if (AGift.MethodOfPaymentCode != null)
            {
                AGift.MethodOfPaymentCode = AGift.MethodOfPaymentCode.ToUpper();
            }

            if (AGift.ReceiptLetterCode != null)
            {
                AGift.ReceiptLetterCode = AGift.ReceiptLetterCode.ToUpper();
            }

            if (HasExtraColumns)
            {
                TCommonImport.ImportInt32(ref FImportLine, FDelimiter, Catalog.GetString("Receipt number"),
                    FMainDS.AGift.ColumnReceiptNumber, ARowNumber, AMessages, null);
                TCommonImport.ImportBoolean(ref FImportLine, FDelimiter, Catalog.GetString("First time gift"),
                    FMainDS.AGift.ColumnFirstTimeGift, ARowNumber, AMessages, null);
                TCommonImport.ImportBoolean(ref FImportLine, FDelimiter, Catalog.GetString("Receipt printed"),
                    FMainDS.AGift.ColumnReceiptPrinted, ARowNumber, AMessages, null);
            }

            AImportMessage = Catalog.GetString("Importing the gift details");

            if ((APreviousGift != null) && (AGift.DonorKey == APreviousGift.DonorKey)
                && (AGift.MethodOfGivingCode == APreviousGift.MethodOfGivingCode)
                && (AGift.MethodOfPaymentCode == APreviousGift.MethodOfPaymentCode)
                && (AGift.Reference == APreviousGift.Reference)
                && (AGift.ReceiptLetterCode == APreviousGift.ReceiptLetterCode)
                && (AGift.ReceiptNumber == APreviousGift.ReceiptNumber)
                && (AGift.FirstTimeGift == APreviousGift.FirstTimeGift)
                && (AGift.ReceiptPrinted == APreviousGift.ReceiptPrinted))
            {
                // this row is a new detail for the previousGift
                AGift = APreviousGift;
                AGift.LastDetailNumber++;
                AGiftDetails.DetailNumber = AGift.LastDetailNumber;
            }
            else
            {
                APreviousGift = AGift;
                AGift.LedgerNumber = AGiftBatch.LedgerNumber;
                AGift.BatchNumber = AGiftBatch.BatchNumber;
                AGift.GiftTransactionNumber = AGiftBatch.LastGiftNumber + 1;
                AGiftBatch.LastGiftNumber++;
                AGift.LastDetailNumber = 1;
                FMainDS.AGift.Rows.Add(AGift);
                AGiftDetails.DetailNumber = 1;
            }

            AGiftDetails.LedgerNumber = AGift.LedgerNumber;
            AGiftDetails.BatchNumber = AGiftBatch.BatchNumber;
            AGiftDetails.GiftTransactionNumber = AGift.GiftTransactionNumber;
            FMainDS.AGiftDetail.Rows.Add(AGiftDetails);

            AGiftDetails.RecipientKey = TCommonImport.ImportInt64(ref FImportLine, FDelimiter, Catalog.GetString("Recipient key"),
                FMainDS.AGiftDetail.ColumnRecipientKey, ARowNumber, AMessages, null);

            TCommonImport.ImportString(ref FImportLine, FDelimiter, Catalog.GetString(
                    "short name of recipient (unused)"), null, ARowNumber, AMessages, null);                           // unused

            if (HasExtraColumns)
            {
                TCommonImport.ImportInt32(ref FImportLine, FDelimiter, Catalog.GetString("Recipient ledger number"),
                    FMainDS.AGiftDetail.ColumnRecipientLedgerNumber, ARowNumber, AMessages, null);
            }

            // we always calculate RecipientLedgerNumber
            AGiftDetails.RecipientLedgerNumber = TGiftTransactionWebConnector.GetRecipientFundNumber(
                AGiftDetails.RecipientKey, AGiftBatch.GlEffectiveDate);

            decimal currentGiftAmount =
                TCommonImport.ImportDecimal(ref FImportLine, FDelimiter, FCultureInfoNumberFormat, Catalog.GetString("Gift amount"),
                    FMainDS.AGiftDetail.ColumnGiftTransactionAmount, ARowNumber, AMessages, null);
            AGiftDetails.GiftTransactionAmount = currentGiftAmount;     // amount in batch currency
            ATotalBatchAmount += currentGiftAmount;

            AGiftDetails.GiftAmount = GLRoutines.Divide(currentGiftAmount, AGiftBatch.ExchangeRateToBase);      // amount in ledger currency

            if (HasExtraColumns)
            {
                // amount in international currency
                TCommonImport.ImportDecimal(ref FImportLine, FDelimiter, FCultureInfoNumberFormat, Catalog.GetString("Gift amount intl"),
                    FMainDS.AGiftDetail.ColumnGiftAmountIntl, ARowNumber, AMessages, null);
            }
            else if (AIntlRateFromBase > 0.0m)
            {
                AGiftDetails.GiftAmountIntl = GLRoutines.Divide(AGiftDetails.GiftAmount, AIntlRateFromBase, 2);
            }

            AGiftDetails.ConfidentialGiftFlag = TCommonImport.ImportBoolean(ref FImportLine, FDelimiter, Catalog.GetString("Confidential gift"),
                FMainDS.AGiftDetail.ColumnConfidentialGiftFlag, ARowNumber, AMessages, null);
            AGiftDetails.MotivationGroupCode = TCommonImport.ImportString(ref FImportLine, FDelimiter, Catalog.GetString("Motivation group code"),
                FMainDS.AGiftDetail.ColumnMotivationGroupCode, ARowNumber, AMessages, null).ToUpper();
            AGiftDetails.MotivationDetailCode = TCommonImport.ImportString(ref FImportLine, FDelimiter, Catalog.GetString("Motivation detail"),
                FMainDS.AGiftDetail.ColumnMotivationDetailCode, ARowNumber, AMessages, null).ToUpper();

            if (HasExtraColumns)
            {
                TCommonImport.ImportString(ref FImportLine, FDelimiter, Catalog.GetString("Cost centre code"),
                    FMainDS.AGiftDetail.ColumnCostCentreCode, ARowNumber, AMessages, null);
            }

            // "In Petra Cost Centre is always inferred from recipient field and motivation detail so is not needed in the import."
            AGiftDetails.CostCentreCode = TGiftTransactionWebConnector.RetrieveCostCentreCodeForRecipient(
                AGiftDetails.LedgerNumber, AGiftDetails.RecipientKey, AGiftDetails.RecipientLedgerNumber,
                AGift.DateEntered, AGiftDetails.MotivationGroupCode, AGiftDetails.MotivationDetailCode);

            // All the remaining columns are optional and can contain database NULL
            AGiftDetails.GiftCommentOne = TCommonImport.ImportString(ref FImportLine, FDelimiter, Catalog.GetString("Gift comment one"),
                FMainDS.AGiftDetail.ColumnGiftCommentOne, ARowNumber, AMessages, null, false);
            string commentOneType = TCommonImport.ImportString(ref FImportLine, FDelimiter, Catalog.GetString("Comment one type"),
                FMainDS.AGiftDetail.ColumnCommentOneType, ARowNumber, AMessages, null, false);

            AGiftDetails.MailingCode = TCommonImport.ImportString(ref FImportLine, FDelimiter, Catalog.GetString("Mailing code"),
                FMainDS.AGiftDetail.ColumnMailingCode, ARowNumber, AMessages, null, false);

            AGiftDetails.GiftCommentTwo = TCommonImport.ImportString(ref FImportLine, FDelimiter, Catalog.GetString("Gift comment two"),
                FMainDS.AGiftDetail.ColumnGiftCommentTwo, ARowNumber, AMessages, null, false);
            string commentTwoType = TCommonImport.ImportString(ref FImportLine, FDelimiter, Catalog.GetString("Comment two type"),
                FMainDS.AGiftDetail.ColumnCommentTwoType, ARowNumber, AMessages, null, false);
            AGiftDetails.GiftCommentThree = TCommonImport.ImportString(ref FImportLine, FDelimiter, Catalog.GetString("Gift comment three"),
                FMainDS.AGiftDetail.ColumnGiftCommentThree, ARowNumber, AMessages, null, false);
            string commentThreeType = TCommonImport.ImportString(ref FImportLine, FDelimiter, Catalog.GetString("Comment three type"),
                FMainDS.AGiftDetail.ColumnCommentThreeType, ARowNumber, AMessages, null, false);

            SetCommentTypeCase(ref commentOneType);
            AGiftDetails.CommentOneType = commentOneType;

            SetCommentTypeCase(ref commentTwoType);
            AGiftDetails.CommentTwoType = commentTwoType;

            SetCommentTypeCase(ref commentThreeType);
            AGiftDetails.CommentThreeType = commentThreeType;

            if (AGiftDetails.MailingCode != null)
            {
                AGiftDetails.MailingCode = AGiftDetails.MailingCode.ToUpper();
            }

            // Find the default Tax deductabilty from the motivation detail. This ensures that the column can be missing.
            AMotivationDetailRow motivationDetailRow = (AMotivationDetailRow)AMotivationDetailTable.Rows.Find(
                new object[] { FLedgerNumber, AGiftDetails.MotivationGroupCode, AGiftDetails.MotivationDetailCode });
            string defaultTaxDeductible =
                ((motivationDetailRow != null) && !motivationDetailRow.IsTaxDeductibleAccountCodeNull()
                 && motivationDetailRow.TaxDeductible) ? "yes" : "no";

            AGiftDetails.TaxDeductible = TCommonImport.ImportBoolean(ref FImportLine, FDelimiter, Catalog.GetString("Tax deductible"),
                FMainDS.AGiftDetail.ColumnTaxDeductible, ARowNumber, AMessages, null, defaultTaxDeductible);

            // Account Codes are always inferred from the motivation detail and so is not needed in the import.
            string NewAccountCode = null;
            string NewTaxDeductibleAccountCode = null;

            // get up-to-date account codes
            if (motivationDetailRow != null)
            {
                NewAccountCode = motivationDetailRow.AccountCode;
                NewTaxDeductibleAccountCode = motivationDetailRow.TaxDeductibleAccountCode;
            }

            AGiftDetails.AccountCode = NewAccountCode;
            AGiftDetails.TaxDeductibleAccountCode = NewTaxDeductibleAccountCode;

            // Date entered cannot be imported although it can be modified in the GUI.
            // This is because it would have to be the last column in the import for compatibility
            // but it belongs with the gift and not the detail so it would need to go in an earlier column.
            // For now the import date entered is the effective date.
            AGift.DateEntered = AGiftBatch.GlEffectiveDate;

            // Enforce the correct case for our GIFT constant
            if (String.Compare(AGiftDetails.MotivationGroupCode, MFinanceConstants.MOTIVATION_GROUP_GIFT, true) == 0)
            {
                AGiftDetails.MotivationGroupCode = MFinanceConstants.MOTIVATION_GROUP_GIFT;
            }
        } // Parse TransactionLine
        /// <summary>
        /// this supports the batch export files from Petra 2.x.
        /// Each line starts with a type specifier, B for batch, J for journal, T for transaction
        /// </summary>
        public void ImportBatches(TGiftImportDataSourceEnum AImportSource)
        {
            bool ok = false;
            String importString;
            String impOptions;
            OpenFileDialog dialog = null;

            if (FPetraUtilsObject.HasChanges)
            {
                // saving failed, therefore do not try to post
                MessageBox.Show(Catalog.GetString("Please save before calling this function!"), Catalog.GetString(
                        "Failure"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            FdlgSeparator = new TDlgSelectCSVSeparator(false);

            if (AImportSource == TGiftImportDataSourceEnum.FromClipboard)
            {
                importString = Clipboard.GetText(TextDataFormat.UnicodeText);

                if ((importString == null) || (importString.Length == 0))
                {
                    MessageBox.Show(Catalog.GetString("Please first copy data from your spreadsheet application!"),
                        Catalog.GetString("Failure"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                impOptions = TUserDefaults.GetStringDefault("Imp Options", ";American");
                String dateFormatString = TUserDefaults.GetStringDefault("Imp Date", "MDY");
                FdlgSeparator = new TDlgSelectCSVSeparator(false);
                FdlgSeparator.SelectedSeparator = "\t";
                FdlgSeparator.CSVData = importString;
                FdlgSeparator.DateFormat = dateFormatString;

                if (impOptions.Length > 1)
                {
                    FdlgSeparator.NumberFormat = impOptions.Substring(1);
                }
            }
            else if (AImportSource == TGiftImportDataSourceEnum.FromFile)
            {
                dialog = new OpenFileDialog();

                dialog.FileName = TUserDefaults.GetStringDefault("Imp Filename",
                    TClientSettings.GetExportPath() + Path.DirectorySeparatorChar + "import.csv");

                dialog.Title = Catalog.GetString("Import Batches from CSV File");
                dialog.Filter = Catalog.GetString("Gift Batches files (*.csv)|*.csv");
                impOptions = TUserDefaults.GetStringDefault("Imp Options", ";" + TDlgSelectCSVSeparator.NUMBERFORMAT_AMERICAN);

                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    Boolean fileCanOpen = FdlgSeparator.OpenCsvFile(dialog.FileName);

                    if (!fileCanOpen)
                    {
                        MessageBox.Show(Catalog.GetString("Unable to open file."),
                            Catalog.GetString("Gift Import"),
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Stop);
                        return;
                    }

                    importString = File.ReadAllText(dialog.FileName);

                    String dateFormatString = TUserDefaults.GetStringDefault("Imp Date", "MDY");
                    FdlgSeparator.DateFormat = dateFormatString;

                    if (impOptions.Length > 1)
                    {
                        FdlgSeparator.NumberFormat = impOptions.Substring(1);
                    }

                    FdlgSeparator.SelectedSeparator = impOptions.Substring(0, 1);
                }
                else
                {
                    return;
                }
            }
            else
            {
                // unknown source!!  The following need a value...
                impOptions = String.Empty;
                importString = String.Empty;
            }

            if (FdlgSeparator.ShowDialog() == DialogResult.OK)
            {
                Hashtable requestParams = new Hashtable();

                requestParams.Add("ALedgerNumber", FLedgerNumber);
                requestParams.Add("Delimiter", FdlgSeparator.SelectedSeparator);
                requestParams.Add("DateFormatString", FdlgSeparator.DateFormat);
                requestParams.Add("NumberFormat", FdlgSeparator.NumberFormat);
                requestParams.Add("NewLine", Environment.NewLine);

                bool Repeat = true;

                while (Repeat)
                {
                    Repeat = false;

                    TVerificationResultCollection AMessages = new TVerificationResultCollection();
                    GiftBatchTDSAGiftDetailTable NeedRecipientLedgerNumber = new GiftBatchTDSAGiftDetailTable();

                    Thread ImportThread = new Thread(() => ImportGiftBatches(
                            requestParams,
                            importString,
                            out AMessages,
                            out ok,
                            out NeedRecipientLedgerNumber));

                    using (TProgressDialog ImportDialog = new TProgressDialog(ImportThread))
                    {
                        ImportDialog.ShowDialog();
                    }

                    // If NeedRecipientLedgerNumber contains data then AMessages will only ever contain
                    // one message alerting the user that no data has been imported.
                    // We do not want to show this as we will be displaying another more detailed message.
                    if (NeedRecipientLedgerNumber.Rows.Count == 0)
                    {
                        ShowMessages(AMessages);
                    }

                    // if the import contains gifts with Motivation Group 'GIFT' and that have a Family recipient with no Gift Destination
                    // then the import will have failed and we need to alert the user
                    if (NeedRecipientLedgerNumber.Rows.Count > 0)
                    {
                        bool OfferToRunImportAgain = true;
                        bool DoNotShowMessageBoxEverytime = false;
                        TFrmExtendedMessageBox.TResult Result = TFrmExtendedMessageBox.TResult.embrUndefined;
                        int count = 1;

                        // for each gift in which the recipient needs a Git Destination
                        foreach (GiftBatchTDSAGiftDetailRow Row in NeedRecipientLedgerNumber.Rows)
                        {
                            if (!DoNotShowMessageBoxEverytime)
                            {
                                string CheckboxText = string.Empty;

                                // only show checkbox if there is at least one more occurance of this error
                                if (NeedRecipientLedgerNumber.Rows.Count - count > 0)
                                {
                                    CheckboxText = string.Format(
                                        Catalog.GetString("Do this for all further occurances ({0})?"), NeedRecipientLedgerNumber.Rows.Count - count);
                                }

                                TFrmExtendedMessageBox extendedMessageBox = new TFrmExtendedMessageBox(FPetraUtilsObject.GetForm());

                                extendedMessageBox.ShowDialog(string.Format(
                                        Catalog.GetString(
                                            "Gift Import has been cancelled as the recipient '{0}' ({1}) has no Gift Destination assigned."),
                                        Row.RecipientDescription, Row.RecipientKey) +
                                    "\n\r\n\r\n\r" +
                                    Catalog.GetString("Do you want to assign a Gift Destination to this partner now?"),
                                    Catalog.GetString("Import Errors"),
                                    CheckboxText,
                                    TFrmExtendedMessageBox.TButtons.embbYesNo, TFrmExtendedMessageBox.TIcon.embiWarning);
                                Result = extendedMessageBox.GetResult(out DoNotShowMessageBoxEverytime);
                            }

                            if (Result == TFrmExtendedMessageBox.TResult.embrYes)
                            {
                                // allow the user to assign a Gift Destingation
                                TFrmGiftDestination GiftDestinationForm = new TFrmGiftDestination(FPetraUtilsObject.GetForm(), Row.RecipientKey);
                                GiftDestinationForm.ShowDialog();
                            }
                            else
                            {
                                OfferToRunImportAgain = false;

                                if (DoNotShowMessageBoxEverytime)
                                {
                                    break;
                                }
                            }

                            count++;
                        }

                        // if the user has clicked yes to assigning Gift Destinations then offer to restart the import
                        if (OfferToRunImportAgain
                            && (MessageBox.Show(Catalog.GetString("Would you like to import this Gift Batch again?"),
                                    Catalog.GetString("Gift Import"), MessageBoxButtons.YesNo, MessageBoxIcon.Question,
                                    MessageBoxDefaultButton.Button2)
                                == DialogResult.Yes))
                        {
                            Repeat = true;
                        }
                    }
                }
            }

            if (ok)
            {
                MessageBox.Show(Catalog.GetString("Your data was imported successfully!"),
                    Catalog.GetString("Gift Import"),
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);

                SaveUserDefaults(dialog, impOptions);
                FMyUserControl.LoadBatchesForCurrentYear();
                FPetraUtilsObject.DisableSaveButton();
            }
        }
        /// <summary>
        /// Main method to post a specified batch
        /// </summary>
        /// <param name="ACurrentBatchRow">The batch row to post</param>
        /// <param name="ARefreshGUIAfterPosting">Will be set to true if the GUI should be updated.  Can be true even if Posting fails
        /// <param name="AWarnOfInactiveValues">True means user is warned if inactive values exist</param>
        /// <param name="ADonorZeroIsValid"></param>
        /// <param name="ARecipientZeroIsValid"></param>
        /// <param name="APostingAlreadyConfirmed">True means ask user if they want to post</param>
        /// if the server gets a SerializableTransactionException</param>
        /// <returns>True if the batch was successfully posted</returns>
        public bool PostBatch(AGiftBatchRow ACurrentBatchRow,
                              out bool ARefreshGUIAfterPosting,
                              bool AWarnOfInactiveValues    = true,
                              bool ADonorZeroIsValid        = false,
                              bool ARecipientZeroIsValid    = false,
                              bool APostingAlreadyConfirmed = false)
        {
            ARefreshGUIAfterPosting = false;

            if ((ACurrentBatchRow == null) || (ACurrentBatchRow.BatchStatus != MFinanceConstants.BATCH_UNPOSTED))
            {
                return(false);
            }

            FSelectedBatchNumber = ACurrentBatchRow.BatchNumber;

            //Make sure that all control data is in dataset
            FMyForm.GetLatestControlData();

            //Copy all batch data to new table
            GiftBatchTDSAGiftDetailTable BatchGiftDetails = new GiftBatchTDSAGiftDetailTable();
            DataView BatchGiftDetailsDV = new DataView(FMainDS.AGiftDetail);

            BatchGiftDetailsDV.RowFilter = string.Format("{0}={1}",
                                                         AGiftDetailTable.GetBatchNumberDBName(),
                                                         FSelectedBatchNumber);

            BatchGiftDetailsDV.Sort = string.Format("{0} ASC, {1} ASC, {2} ASC",
                                                    AGiftDetailTable.GetBatchNumberDBName(),
                                                    AGiftDetailTable.GetGiftTransactionNumberDBName(),
                                                    AGiftDetailTable.GetDetailNumberDBName());

            foreach (DataRowView drv in BatchGiftDetailsDV)
            {
                GiftBatchTDSAGiftDetailRow gBRow = (GiftBatchTDSAGiftDetailRow)drv.Row;
                BatchGiftDetails.Rows.Add((object[])gBRow.ItemArray.Clone());
            }

            //Save and check for inactive values and ex-workers and anonymous gifts
            if (FPetraUtilsObject.HasChanges)
            {
                //Keep this conditional check separate from the one above so that it only gets called
                // when necessary and doesn't result in the executon of the same method
                if (!FMyForm.SaveChangesForPosting(BatchGiftDetails))
                {
                    return(false);
                }
                else
                {
                    APostingAlreadyConfirmed = true;
                }
            }
            else
            {
                //This has to be called here because if there are no changes then the DataSavingValidating
                // method which calls the method below, will not run.
                if (!FMyForm.GetBatchControl().AllowInactiveFieldValues(ref APostingAlreadyConfirmed,
                                                                        TExtraGiftBatchChecks.GiftBatchAction.POSTING) ||
                    FMyForm.GiftHasExWorkerOrAnon(BatchGiftDetails)
                    )
                {
                    return(false);
                }
            }

            //Check hash total validity
            if ((ACurrentBatchRow.HashTotal != 0) &&
                (ACurrentBatchRow.BatchTotal != ACurrentBatchRow.HashTotal))
            {
                MessageBox.Show(String.Format(Catalog.GetString(
                                                  "The gift batch total ({0}) for batch {1} does not equal the hash total ({2})!"),
                                              StringHelper.FormatUsingCurrencyCode(ACurrentBatchRow.BatchTotal, ACurrentBatchRow.CurrencyCode),
                                              ACurrentBatchRow.BatchNumber,
                                              StringHelper.FormatUsingCurrencyCode(ACurrentBatchRow.HashTotal, ACurrentBatchRow.CurrencyCode)),
                                "Post Gift Batch");

                return(false);
            }

            //Check for missing international exchange rate
            bool IsTransactionInIntlCurrency = false;

            FMyForm.WarnAboutMissingIntlExchangeRate = true;

            if (FMyForm.InternationalCurrencyExchangeRate(ACurrentBatchRow, out IsTransactionInIntlCurrency, true) == 0)
            {
                return(false);
            }

            //Check for zero Donors or Recipients
            if (!ADonorZeroIsValid)
            {
                DataView batchGiftDV = new DataView(FMainDS.AGift);

                batchGiftDV.RowFilter = string.Format("{0}={1} And {2}=0",
                                                      AGiftTable.GetBatchNumberDBName(),
                                                      FSelectedBatchNumber,
                                                      AGiftTable.GetDonorKeyDBName());

                int numDonorZeros = batchGiftDV.Count;

                if (numDonorZeros > 0)
                {
                    string messageListOfOffendingGifts =
                        String.Format(Catalog.GetString(
                                          "Gift Batch {0} contains {1} gift detail(s) with Donor 0000000. Please fix before posting!{2}{2}"),
                                      FSelectedBatchNumber,
                                      numDonorZeros,
                                      Environment.NewLine);

                    string listOfOffendingRows = string.Empty;

                    listOfOffendingRows += "Gift" + Environment.NewLine;
                    listOfOffendingRows += "------------";

                    foreach (DataRowView drv in batchGiftDV)
                    {
                        AGiftRow giftRow = (AGiftRow)drv.Row;

                        listOfOffendingRows += String.Format("{0}{1:0000}",
                                                             Environment.NewLine,
                                                             giftRow.GiftTransactionNumber);
                    }

                    TFrmExtendedMessageBox extendedMessageBox = new TFrmExtendedMessageBox(FMyForm);

                    extendedMessageBox.ShowDialog((messageListOfOffendingGifts + listOfOffendingRows),
                                                  Catalog.GetString("Post Batch Error"), string.Empty,
                                                  TFrmExtendedMessageBox.TButtons.embbOK,
                                                  TFrmExtendedMessageBox.TIcon.embiWarning);

                    return(false);
                }
            }

            if (!ARecipientZeroIsValid)
            {
                DataView batchGiftDetailsDV = new DataView(FMainDS.AGiftDetail);

                batchGiftDetailsDV.RowFilter = string.Format("{0}={1} And {2}=0",
                                                             AGiftDetailTable.GetBatchNumberDBName(),
                                                             FSelectedBatchNumber,
                                                             AGiftDetailTable.GetRecipientKeyDBName());

                int numRecipientZeros = batchGiftDetailsDV.Count;

                if (numRecipientZeros > 0)
                {
                    string messageListOfOffendingGifts =
                        String.Format(Catalog.GetString(
                                          "Gift Batch {0} contains {1} gift detail(s) with Recipient 0000000. Please fix before posting!{2}{2}"),
                                      FSelectedBatchNumber,
                                      numRecipientZeros,
                                      Environment.NewLine);

                    string listOfOffendingRows = string.Empty;

                    listOfOffendingRows += "Gift   Detail" + Environment.NewLine;
                    listOfOffendingRows += "-------------------";

                    foreach (DataRowView drv in batchGiftDetailsDV)
                    {
                        AGiftDetailRow giftDetailRow = (AGiftDetailRow)drv.Row;

                        listOfOffendingRows += String.Format("{0}{1:0000}  {2:00}",
                                                             Environment.NewLine,
                                                             giftDetailRow.GiftTransactionNumber,
                                                             giftDetailRow.DetailNumber);
                    }

                    TFrmExtendedMessageBox extendedMessageBox = new TFrmExtendedMessageBox(FMyForm);

                    extendedMessageBox.ShowDialog((messageListOfOffendingGifts + listOfOffendingRows),
                                                  Catalog.GetString("Post Batch Error"), string.Empty,
                                                  TFrmExtendedMessageBox.TButtons.embbOK,
                                                  TFrmExtendedMessageBox.TIcon.embiWarning);

                    return(false);
                }
            }

            //Check for inactive KeyMinistries
            DataTable GiftsWithInactiveKeyMinistries;
            bool      ModifiedDetails = false;

            if (AWarnOfInactiveValues && TRemote.MFinance.Gift.WebConnectors.InactiveKeyMinistriesFoundInBatch(FLedgerNumber, FSelectedBatchNumber,
                                                                                                               out GiftsWithInactiveKeyMinistries, false))
            {
                int numInactiveValues = GiftsWithInactiveKeyMinistries.Rows.Count;

                string messageNonModifiedBatch =
                    String.Format(Catalog.GetString("Gift Batch {0} contains {1} inactive key ministries. Please fix before posting!{2}{2}"),
                                  FSelectedBatchNumber,
                                  numInactiveValues,
                                  Environment.NewLine);
                string messageModifiedBatch =
                    String.Format(Catalog.GetString(
                                      "Reversal/Adjustment Gift Batch {0} contains {1} inactive key ministries. Do you still want to post?{2}{2}"),
                                  FSelectedBatchNumber,
                                  numInactiveValues,
                                  Environment.NewLine);

                string listOfOffendingRows = string.Empty;

                listOfOffendingRows += "Gift      Detail   Recipient          KeyMinistry" + Environment.NewLine;
                listOfOffendingRows += "-------------------------------------------------------------------------------";

                foreach (DataRow dr in GiftsWithInactiveKeyMinistries.Rows)
                {
                    listOfOffendingRows += String.Format("{0}{1:0000}    {2:00}        {3:00000000000}    {4}",
                                                         Environment.NewLine,
                                                         dr[0],
                                                         dr[1],
                                                         dr[2],
                                                         dr[3]);

                    bool isModified = Convert.ToBoolean(dr[4]);

                    if (isModified)
                    {
                        ModifiedDetails = true;
                    }
                }

                TFrmExtendedMessageBox extendedMessageBox = new TFrmExtendedMessageBox(FMyForm);

                if (ModifiedDetails)
                {
                    if (extendedMessageBox.ShowDialog((messageModifiedBatch + listOfOffendingRows),
                                                      Catalog.GetString("Post Batch"), string.Empty,
                                                      TFrmExtendedMessageBox.TButtons.embbYesNo,
                                                      TFrmExtendedMessageBox.TIcon.embiWarning) == TFrmExtendedMessageBox.TResult.embrYes)
                    {
                        APostingAlreadyConfirmed = true;
                    }
                    else
                    {
                        return(false);
                    }
                }
                else
                {
                    extendedMessageBox.ShowDialog((messageNonModifiedBatch + listOfOffendingRows),
                                                  Catalog.GetString("Post Batch Error"), string.Empty,
                                                  TFrmExtendedMessageBox.TButtons.embbOK,
                                                  TFrmExtendedMessageBox.TIcon.embiWarning);

                    return(false);
                }
            }

            // ask if the user really wants to post the batch
            if (!APostingAlreadyConfirmed &&
                (MessageBox.Show(String.Format(Catalog.GetString("Do you really want to post gift batch {0}?"), FSelectedBatchNumber),
                                 Catalog.GetString("Confirm posting of Gift Batch"),
                                 MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes))
            {
                return(false);
            }

            TVerificationResultCollection Verifications = new TVerificationResultCollection();

            try
            {
                FPostingInProgress = true;

                Thread postingThread = new Thread(() => PostGiftBatch(out Verifications));
                postingThread.SetApartmentState(ApartmentState.STA);
                using (TProgressDialog dialog = new TProgressDialog(postingThread))
                {
                    dialog.ShowDialog();
                }

                if (TVerificationHelper.ResultsContainErrorCode(Verifications, PetraErrorCodes.ERR_DB_SERIALIZATION_EXCEPTION))
                {
                    TConcurrentServerTransactions.ShowTransactionSerializationExceptionDialog();
                    ARefreshGUIAfterPosting = true;
                    return(false);
                }
                else if (!TVerificationHelper.IsNullOrOnlyNonCritical(Verifications))
                {
                    TFrmExtendedMessageBox extendedMessageBox = new TFrmExtendedMessageBox(FMyForm);

                    StringBuilder errorMessages = new StringBuilder();
                    int           counter       = 0;

                    errorMessages.AppendLine(Catalog.GetString("________________________Gift Posting Errors________________________"));
                    errorMessages.AppendLine();

                    foreach (TVerificationResult verif in Verifications)
                    {
                        counter++;
                        errorMessages.AppendLine(counter.ToString("000") + " - " + verif.ResultText);
                        errorMessages.AppendLine();
                    }

                    extendedMessageBox.ShowDialog(errorMessages.ToString(),
                                                  Catalog.GetString("Post Batch Error"),
                                                  string.Empty,
                                                  TFrmExtendedMessageBox.TButtons.embbOK,
                                                  TFrmExtendedMessageBox.TIcon.embiWarning);
                }
                else
                {
                    MessageBox.Show(Catalog.GetString("The batch has been posted successfully!"));
                    ARefreshGUIAfterPosting = true;
                }
            }
            catch (Exception ex)
            {
                TLogging.LogException(ex, Utilities.GetMethodSignature());
                throw;
            }
            finally
            {
                FPostingInProgress = false;
            }

            return(true);
        }
Example #13
0
        /// <summary>
        /// Looks for gifts where the recipient is an ExWorker and asks the user if they want to continue.
        /// (Make sure GetDataFromControls is called before this method so that AMainDS is up-to-date.)
        /// </summary>
        /// <param name="AAction">Why this method is being called</param>
        /// <param name="AMainDS"></param>
        /// <param name="APetraUtilsObject"></param>
        /// <param name="APostingGiftDetails">Only used when being called in order to carry out a batch posting</param>
        /// <returns>Returns true if saving/posting can continue</returns>
        public static bool CanContinueWithAnyExWorkers(GiftBatchAction AAction,
                                                       GiftBatchTDS AMainDS,
                                                       TFrmPetraEditUtils APetraUtilsObject,
                                                       DataTable APostingGiftDetails = null)
        {
            DataTable ExWorkers     = null;
            string    Msg           = string.Empty;
            int       BatchNumber   = -1;
            int       ExWorkerGifts = 0;

            string ExWorkerSpecialType = TSystemDefaults.GetSystemDefault(SharedConstants.SYSDEFAULT_EXWORKERSPECIALTYPE, "EX-WORKER");

            // first check for Ex-Workers in the batch that is being posted/submitted (if a batch is being posted/submitted)
            if ((APostingGiftDetails != null) && (APostingGiftDetails.Rows.Count > 0))
            {
                ExWorkers      = TRemote.MFinance.Gift.WebConnectors.FindGiftRecipientExWorker(APostingGiftDetails, BatchNumber);
                ExWorkerGifts += ExWorkers.Rows.Count;

                Msg = GetExWorkersString(AAction, ExWorkerSpecialType, ExWorkers);

                if (ExWorkers.Rows.Count > 0)
                {
                    BatchNumber = (int)APostingGiftDetails.Rows[0][GiftBatchTDSAGiftDetailTable.GetBatchNumberDBName()];
                }
            }

            // check for Ex-Workers in all added and modified data
            if (APetraUtilsObject.HasChanges)
            {
                DataTable Changes = new DataTable();

                if (AMainDS.AGiftDetail.GetChangesTyped() != null)
                {
                    Changes.Merge(AMainDS.AGiftDetail.GetChangesTyped());
                }
                else if (AMainDS.ARecurringGiftDetail.GetChangesTyped() != null)
                {
                    Changes.Merge(AMainDS.ARecurringGiftDetail.GetChangesTyped());
                }

                if ((Changes != null) && (Changes.Rows.Count > 0))
                {
                    ExWorkers      = TRemote.MFinance.Gift.WebConnectors.FindGiftRecipientExWorker(Changes, BatchNumber);
                    ExWorkerGifts += ExWorkers.Rows.Count;

                    Msg += GetExWorkersString(null, ExWorkerSpecialType, ExWorkers);
                }
            }

            // alert the user to any recipients who are Ex-Workers
            if (Msg != string.Empty)
            {
                if (AAction == GiftBatchAction.SAVING)
                {
                    Msg += Catalog.GetString("Do you want to continue with saving anyway?");
                }
                else
                {
                    // singular
                    if (ExWorkerGifts == 1)
                    {
                        if (AAction == GiftBatchAction.POSTING)
                        {
                            Msg += Catalog.GetString("This gift will need to be saved before this batch can be posted.");
                        }
                        else if (AAction == GiftBatchAction.NEWBATCH)
                        {
                            Msg += Catalog.GetString("This gift will need to be saved before a new batch can be created.");
                        }
                        else if (AAction == GiftBatchAction.CANCELLING)
                        {
                            Msg += Catalog.GetString("This gift will need to be saved before this batch can be cancelled.");
                        }
                        else if (AAction == GiftBatchAction.SUBMITTING)
                        {
                            Msg += Catalog.GetString("This gift will need to be saved before this batch can be submitted.");
                        }
                        else if (AAction == GiftBatchAction.DELETING)
                        {
                            Msg += Catalog.GetString("This gift will need to be saved before this batch can be deleted.");
                        }
                    }
                    // plural
                    else
                    {
                        if (AAction == GiftBatchAction.POSTING)
                        {
                            Msg += Catalog.GetString("These gifts will need to be saved before this batch can be posted.");
                        }
                        else if (AAction == GiftBatchAction.NEWBATCH)
                        {
                            Msg += Catalog.GetString("These gifts will need to be saved before a new batch can be created.");
                        }
                        else if (AAction == GiftBatchAction.CANCELLING)
                        {
                            Msg += Catalog.GetString("These gifts will need to be saved before this batch can be cancelled.");
                        }
                        else if (AAction == GiftBatchAction.SUBMITTING)
                        {
                            Msg += Catalog.GetString("These gifts will need to be saved before this batch can be submitted.");
                        }
                        else if (AAction == GiftBatchAction.DELETING)
                        {
                            Msg += Catalog.GetString("These gifts will need to be saved before this batch can be deleted.");
                        }
                    }

                    Msg += " " + Catalog.GetString("Do you want to continue?");
                }

                if (MessageBox.Show(
                        Msg, string.Format(Catalog.GetString("{0} Warning"), ExWorkerSpecialType), MessageBoxButtons.YesNo, MessageBoxIcon.Warning)
                    == DialogResult.No)
                {
                    return(false);
                }
            }

            return(true);
        }
Example #14
0
        /// <summary>
        /// Import Gift Transactions from a file
        /// </summary>
        /// <param name="ARequestParams"></param>
        /// <param name="AImportString"></param>
        /// <param name="AGiftBatchNumber"></param>
        /// <param name="ANeedRecipientLedgerNumber"></param>
        /// <param name="AMessages"></param>
        /// <returns></returns>
        public bool ImportGiftTransactions(
            Hashtable ARequestParams,
            String AImportString,
            Int32 AGiftBatchNumber,
            out GiftBatchTDSAGiftDetailTable ANeedRecipientLedgerNumber,
            out TVerificationResultCollection AMessages
            )
        {
            TProgressTracker.InitProgressTracker(DomainManager.GClientID.ToString(),
                Catalog.GetString("Importing Gift Batches"),
                100);

            TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                Catalog.GetString("Initialising"),
                5);

            GiftBatchTDSAGiftDetailTable NeedRecipientLedgerNumber = new GiftBatchTDSAGiftDetailTable();
            TVerificationResultCollection Messages = new TVerificationResultCollection();

            // fix for Mono issue with out parameter: https://bugzilla.xamarin.com/show_bug.cgi?id=28196
            AMessages = Messages;

            FMainDS = new GiftBatchTDS();
            StringReader sr = new StringReader(AImportString);

            // Parse the supplied parameters
            FDelimiter = (String)ARequestParams["Delimiter"];
            FLedgerNumber = (Int32)ARequestParams["ALedgerNumber"];
            FDateFormatString = (String)ARequestParams["DateFormatString"];
            String NumberFormat = (String)ARequestParams["NumberFormat"];
            FNewLine = (String)ARequestParams["NewLine"];

            // Set culture from parameters
            FCultureInfoNumberFormat = new CultureInfo(NumberFormat.Equals("American") ? "en-US" : "de-DE");
            FCultureInfoDate = new CultureInfo("en-GB");
            FCultureInfoDate.DateTimeFormat.ShortDatePattern = FDateFormatString;

            bool TaxDeductiblePercentageEnabled = Convert.ToBoolean(
                TSystemDefaults.GetSystemDefault(SharedConstants.SYSDEFAULT_TAXDEDUCTIBLEPERCENTAGE, "FALSE"));

            // Initialise our working variables
            decimal totalBatchAmount = 0;
            Boolean CancelledByUser = false;
            string ImportMessage = Catalog.GetString("Initialising");

            // This needs to be initialised because we will be calling the method
            TSharedFinanceValidationHelper.GetValidPeriodDatesDelegate = @TAccountingPeriodsWebConnector.GetPeriodDates;
            TSharedFinanceValidationHelper.GetFirstDayOfAccountingPeriodDelegate = @TAccountingPeriodsWebConnector.GetFirstDayOfAccountingPeriod;

            TDBTransaction Transaction = null;
            bool SubmissionOK = false;
            Int32 RowNumber = 0;

            DBAccess.GDBAccessObj.BeginAutoTransaction(IsolationLevel.Serializable,
                ref Transaction,
                ref SubmissionOK,
                delegate
                {
                    try
                    {
                        // Load supplementary tables that we are going to need for validation
                        ALedgerTable LedgerTable = ALedgerAccess.LoadByPrimaryKey(FLedgerNumber, Transaction);
                        ACostCentreTable CostCentreTable = ACostCentreAccess.LoadViaALedger(FLedgerNumber, Transaction);
                        AAccountTable AccountTable = AAccountAccess.LoadViaALedger(FLedgerNumber, Transaction);
                        AMotivationGroupTable MotivationGroupTable = AMotivationGroupAccess.LoadViaALedger(FLedgerNumber, Transaction);
                        AMotivationDetailTable MotivationDetailTable = AMotivationDetailAccess.LoadViaALedger(FLedgerNumber, Transaction);
                        AMethodOfGivingTable MethodOfGivingTable = AMethodOfGivingAccess.LoadAll(Transaction);
                        AMethodOfPaymentTable MethodOfPaymentTable = AMethodOfPaymentAccess.LoadAll(Transaction);
                        PMailingTable MailingTable = PMailingAccess.LoadAll(Transaction);
                        PFormTable MailingFormTable = TFormTemplatesWebConnector.GetPartnerForms();

                        AGiftBatchTable giftBatchTable = AGiftBatchAccess.LoadByPrimaryKey(FLedgerNumber, AGiftBatchNumber, Transaction);
                        FMainDS.AGiftBatch.ImportRow(giftBatchTable[0]);
                        FMainDS.AcceptChanges();
                        AGiftBatchRow giftBatch = FMainDS.AGiftBatch[0];

                        if (LedgerTable.Rows.Count == 0)
                        {
                            throw new Exception(String.Format(Catalog.GetString("Ledger {0} doesn't exist."), FLedgerNumber));
                        }

                        string LedgerBaseCurrency = ((ALedgerRow)LedgerTable.Rows[0]).BaseCurrency;
                        string LedgerIntlCurrency = ((ALedgerRow)LedgerTable.Rows[0]).IntlCurrency;

                        decimal intlRateFromBase = -1.0m;
                        DateTime firstOfMonth;

                        if (TSharedFinanceValidationHelper.GetFirstDayOfAccountingPeriod(FLedgerNumber,
                                giftBatch.GlEffectiveDate, out firstOfMonth))
                        {
                            intlRateFromBase = TExchangeRateTools.GetCorporateExchangeRate(LedgerBaseCurrency, LedgerIntlCurrency, firstOfMonth,
                                giftBatch.GlEffectiveDate);
                        }

                        ImportMessage = Catalog.GetString("Parsing first line");
                        AGiftRow previousGift = null;

                        // Go round a loop reading the file line by line
                        FImportLine = sr.ReadLine();
                        Boolean ImportingEsr = false;
                        Int32 PercentDone = 10;
                        Int32 PreviousPercentDone = 0;

                        Int32 InitialTextLength = AImportString.Length;
                        Int32 totalRows = AImportString.Split('\n').Length;
                        TValidationControlsDict EmptyControlsDict = new TValidationControlsDict();

                        while (FImportLine != null)
                        {
                            RowNumber++;
                            PercentDone = 10 + ((RowNumber * 90) / totalRows);

                            // skip empty lines and commented lines
                            if ((FImportLine.Trim().Length > 0) && !FImportLine.StartsWith("/*") && !FImportLine.StartsWith("#"))
                            {
                                // number of elements is incremented by 1 as though the line started with 'T'
                                int numberOfElements = StringHelper.GetCSVList(FImportLine, FDelimiter).Count + 1;
                                Boolean IsEsrString = false;

                                if (numberOfElements == 2)
                                {
                                    IsEsrString = ((FImportLine.Trim().Length == 100) && (FImportLine.Substring(53, 2) == "  "));
                                }

                                if (ImportingEsr && !IsEsrString) // I did previously succeed with ESR, but now not so much -
                                {                                 // I'm probably at the last line of the file.
                                    FImportLine = sr.ReadLine();
                                    continue;
                                }

                                if (!IsEsrString)
                                {
                                    // It is a Transaction row
                                    if (numberOfElements < 13) // Perhaps this CSV file is a summary, and can't be imported?
                                    {
                                        Messages.Add(new TVerificationResult(String.Format(MCommonConstants.StrParsingErrorInLine, RowNumber),
                                                Catalog.GetString(
                                                    "Wrong number of gift columns. Expected at least 13 columns. (This may be a summary?)"),
                                                TResultSeverity.Resv_Critical));
                                        FImportLine = sr.ReadLine();
                                        continue;
                                    }
                                }

                                // Parse the line into a new row
                                ImportMessage = Catalog.GetString("Parsing transaction line");
                                Int32 preParseMessageCount = Messages.Count;
                                AGiftRow gift = FMainDS.AGift.NewRowTyped(true);
                                AGiftDetailRow giftDetails = FMainDS.AGiftDetail.NewRowTyped(true);

                                if (IsEsrString)
                                {
                                    ImportingEsr = ParseEsrTransactionLine(
                                        FImportLine,
                                        giftBatch,
                                        gift,
                                        giftDetails,
                                        intlRateFromBase,
                                        MotivationDetailTable,
                                        NeedRecipientLedgerNumber,
                                        Messages
                                        );
                                }
                                else
                                {
                                    ParseTransactionLine(gift,
                                        giftBatch,
                                        ref previousGift,
                                        numberOfElements,
                                        ref totalBatchAmount,
                                        ref ImportMessage,
                                        RowNumber,
                                        intlRateFromBase,
                                        Messages,
                                        MotivationDetailTable,
                                        NeedRecipientLedgerNumber,
                                        giftDetails);
                                }

                                if (Messages.Count == preParseMessageCount)     // No parsing errors so we can validate
                                {                                               // (parsing errors will have assumed, probably invalid, values)
                                    ImportMessage = Catalog.GetString("Validating the gift data");

                                    int messageCountBeforeValidate = preParseMessageCount;

                                    TPartnerClass RecipientClass;
                                    string RecipientDescription;
                                    TPartnerServerLookups.GetPartnerShortName(giftDetails.RecipientKey, out RecipientDescription, out RecipientClass);

                                    // Do our standard validation on this gift
                                    AGiftValidation.Validate(this, gift, ref Messages, EmptyControlsDict);
                                    TSharedFinanceValidation_Gift.ValidateGiftManual(this, gift, giftBatch.BatchYear, giftBatch.BatchPeriod,
                                        null, ref Messages, EmptyControlsDict, MethodOfGivingTable, MethodOfPaymentTable, MailingFormTable);

                                    ImportMessage = Catalog.GetString("Validating the gift details data");

                                    AGiftDetailValidation.Validate(this, giftDetails, ref Messages, EmptyControlsDict);
                                    TSharedFinanceValidation_Gift.ValidateGiftDetailManual(this, (GiftBatchTDSAGiftDetailRow)giftDetails,
                                        ref Messages, EmptyControlsDict, RecipientClass, null, CostCentreTable, AccountTable,
                                        MotivationGroupTable, MotivationDetailTable, MailingTable, giftDetails.RecipientKey);

                                    // Fix up the messages
                                    for (int i = messageCountBeforeValidate; i < Messages.Count; i++)
                                    {
                                        ((TVerificationResult)Messages[i]).OverrideResultContext(String.Format(MCommonConstants.
                                                StrValidationErrorInLine, RowNumber));

                                        if (Messages[i] is TScreenVerificationResult)
                                        {
                                            TVerificationResult downgrade = new TVerificationResult((TScreenVerificationResult)Messages[i]);
                                            Messages.RemoveAt(i);
                                            Messages.Insert(i, downgrade);
                                        }
                                    }
                                }

                                if (TaxDeductiblePercentageEnabled)
                                {
                                    // Sets TaxDeductiblePct and uses it to calculate the tax deductibility amounts for a Gift Detail
                                    TGift.SetDefaultTaxDeductibilityData(ref giftDetails, gift.DateEntered, Transaction);
                                }
                            }

                            if (TProgressTracker.GetCurrentState(DomainManager.GClientID.ToString()).CancelJob == true)
                            {
                                CancelledByUser = true;
                                break;
                            }

                            if (Messages.HasCriticalErrors && (Messages.Count > 100))
                            {
                                // This probably means that it is a big file and the user has made the same mistake many times over
                                break;
                            }

                            // Update progress tracker every few percent
                            if ((PercentDone - PreviousPercentDone) > 3)
                            {
                                TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                                    String.Format(Catalog.GetString("Importing row {0}"), RowNumber),
                                    (PercentDone > 98) ? 98 : PercentDone);
                                PreviousPercentDone = PercentDone;
                            }

                            // Read the next line
                            FImportLine = sr.ReadLine();
                        } // while CSV lines

                        if (CancelledByUser)
                        {
                            Messages.Add(new TVerificationResult(MCommonConstants.StrImportInformation,
                                    String.Format(Catalog.GetString("{0} messages reported."), Messages.Count), TResultSeverity.Resv_Info));
                            Messages.Add(new TVerificationResult(MCommonConstants.StrImportInformation,
                                    "The import was cancelled by the user.", TResultSeverity.Resv_Info));
                            return;
                        }

                        // Finished reading the file - did we have critical errors?
                        if (!TVerificationHelper.IsNullOrOnlyNonCritical(Messages))
                        {
                            TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                                Catalog.GetString("Batch has critical errors"),
                                100);

                            // Record error count
                            Messages.Add(new TVerificationResult(MCommonConstants.StrImportInformation,
                                    String.Format(Catalog.GetString("{0} messages reported."), Messages.Count), TResultSeverity.Resv_Info));

                            if (FImportLine == null)
                            {
                                // We did reach the end of the file
                                Messages.Add(new TVerificationResult(MCommonConstants.StrImportInformation,
                                        Catalog.GetString(
                                            "Reached the end of file but errors occurred. When these errors are fixed the batch will import successfully."),
                                        TResultSeverity.Resv_Info));
                            }
                            else
                            {
                                // We gave up before the end
                                Messages.Add(new TVerificationResult(MCommonConstants.StrImportInformation,
                                        Catalog.GetString(
                                            "Stopped reading the file after generating more than 100 messages.  The file may contian more errors beyond the ones listed here."),
                                        TResultSeverity.Resv_Info));
                            }

                            // we do not want to think about Gift Destination problems if the import has failed for another reason
                            NeedRecipientLedgerNumber.Clear();

                            // Do the 'finally' actions and return false
                            return;
                        }

                        // if the import contains gifts with Motivation Group 'GIFT' and that have a Family recipient with no Gift Destination then the import will fail
                        if (NeedRecipientLedgerNumber.Rows.Count > 0)
                        {
                            // Do the 'finally' actions and return false
                            return;
                        }

                        // Everything is ok, so we can do our finish actions

                        //Update batch total for the last batch entered.
                        if ((giftBatch != null) && !ImportingEsr)
                        {
                            giftBatch.BatchTotal = totalBatchAmount;
                        }

                        TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                            Catalog.GetString("Saving all data into the database"),
                            100);

                        //Finally save pending changes (the last number is updated !)
                        ImportMessage = Catalog.GetString("Saving gift batch");
                        AGiftBatchAccess.SubmitChanges(FMainDS.AGiftBatch, Transaction);
                        FMainDS.AGiftBatch.AcceptChanges();

                        ImportMessage = Catalog.GetString("Saving gifts");
                        AGiftAccess.SubmitChanges(FMainDS.AGift, Transaction);
                        FMainDS.AGift.AcceptChanges();

                        ImportMessage = Catalog.GetString("Saving giftdetails");
                        AGiftDetailAccess.SubmitChanges(FMainDS.AGiftDetail, Transaction);
                        FMainDS.AGiftDetail.AcceptChanges();

                        ImportMessage = Catalog.GetString("Saving ledger");
                        ALedgerAccess.SubmitChanges(LedgerTable, Transaction);
                        LedgerTable.AcceptChanges();

                        // Commit the transaction (we know that we got a new one and can control it)
                        SubmissionOK = true;
                    }
                    catch (Exception ex)
                    {
                        // Parse the exception text for possible references to database foreign keys
                        // Make the message more friendly in that case
                        string friendlyExceptionText = MakeFriendlyFKExceptions(ex);

                        if (RowNumber > 0)
                        {
                            // At least we made a start
                            string msg = ImportMessage;

                            if (friendlyExceptionText.Length > 0)
                            {
                                msg += FNewLine + friendlyExceptionText;
                            }

                            if (ImportMessage.StartsWith(Catalog.GetString("Saving ")))
                            {
                                // Do not display any specific line number because these errors occur outside the parsing loop
                                Messages.Add(new TVerificationResult(MCommonConstants.StrExceptionWhileSavingTransactions,
                                        msg, TResultSeverity.Resv_Critical));
                            }
                            else
                            {
                                Messages.Add(new TVerificationResult(String.Format(MCommonConstants.StrExceptionWhileParsingLine, RowNumber),
                                        msg, TResultSeverity.Resv_Critical));
                            }
                        }
                        else
                        {
                            // We got an exception before we even started parsing the rows (getting a transaction?)
                            Messages.Add(new TVerificationResult(String.Format(MCommonConstants.StrExceptionWhileParsingLine, RowNumber),
                                    friendlyExceptionText, TResultSeverity.Resv_Critical));
                        }

                        TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                            Catalog.GetString("Exception Occurred"),
                            0);

                        SubmissionOK = false;
                    }
                    finally
                    {
                        sr.Close();

                        if (SubmissionOK)
                        {
                            TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                                Catalog.GetString("Gift batch import successful"),
                                100);
                        }
                        else
                        {
                            Messages.Add(new TVerificationResult(MCommonConstants.StrImportInformation,
                                    Catalog.GetString("None of the data from the import was saved."),
                                    TResultSeverity.Resv_Critical));

                            TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                                Catalog.GetString("Data could not be saved."),
                                0);
                        }

                        TProgressTracker.FinishJob(DomainManager.GClientID.ToString());
                    } // end of 'finally'
                });

            // Set our 'out' parameters
            ANeedRecipientLedgerNumber = NeedRecipientLedgerNumber;
            AMessages = Messages;

            return SubmissionOK;
        }
Example #15
0
        /// <summary>
        /// Import Gift batch data
        /// The data file contents from the client is sent as a string, imported in the database
        /// and committed immediately
        /// </summary>
        /// <param name="ARequestParams">Hashtable containing the given params </param>
        /// <param name="AImportString">Big parts of the export file as a simple String</param>
        /// <param name="ANeedRecipientLedgerNumber">Gifts in this table are responsible for failing the
        /// import becuase their Family recipients do not have an active Gift Destination</param>
        /// <param name="AMessages">Additional messages to display in a messagebox</param>
        /// <returns>false if error</returns>
        public bool ImportGiftBatches(
            Hashtable ARequestParams,
            String AImportString,
            out GiftBatchTDSAGiftDetailTable ANeedRecipientLedgerNumber,
            out TVerificationResultCollection AMessages
            )
        {
            TProgressTracker.InitProgressTracker(DomainManager.GClientID.ToString(),
                Catalog.GetString("Importing Gift Batches"),
                100);

            TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                Catalog.GetString("Initialising"),
                0);

            TVerificationResultCollection Messages = new TVerificationResultCollection();

            // fix for Mono issue with out parameter: https://bugzilla.xamarin.com/show_bug.cgi?id=28196
            AMessages = Messages;

            GiftBatchTDSAGiftDetailTable NeedRecipientLedgerNumber = new GiftBatchTDSAGiftDetailTable();

            FMainDS = new GiftBatchTDS();
            StringReader sr = new StringReader(AImportString);

            // Parse the supplied parameters
            FDelimiter = (String)ARequestParams["Delimiter"];
            FLedgerNumber = (Int32)ARequestParams["ALedgerNumber"];
            FDateFormatString = (String)ARequestParams["DateFormatString"];
            String NumberFormat = (String)ARequestParams["NumberFormat"];
            FNewLine = (String)ARequestParams["NewLine"];

            // Set culture from parameters
            FCultureInfoNumberFormat = new CultureInfo(NumberFormat.Equals("American") ? "en-US" : "de-DE");
            FCultureInfoDate = new CultureInfo("en-GB");
            FCultureInfoDate.DateTimeFormat.ShortDatePattern = FDateFormatString;

            bool TaxDeductiblePercentageEnabled = Convert.ToBoolean(
                TSystemDefaults.GetSystemDefault(SharedConstants.SYSDEFAULT_TAXDEDUCTIBLEPERCENTAGE, "FALSE"));

            // Initialise our working variables
            AGiftBatchRow giftBatch = null;
            decimal totalBatchAmount = 0;
            Int32 RowNumber = 0;
            Int32 InitialTextLength = AImportString.Length;
            Int32 TextProcessedLength = 0;
            Int32 PercentDone = 10;
            Int32 PreviousPercentDone = 0;
            Boolean CancelledByUser = false;
            decimal intlRateFromBase = -1.0m;

            string ImportMessage = Catalog.GetString("Initialising");

            // This needs to be initialised because we will be calling the method
            TSharedFinanceValidationHelper.GetValidPeriodDatesDelegate = @TAccountingPeriodsWebConnector.GetPeriodDates;
            TSharedFinanceValidationHelper.GetFirstDayOfAccountingPeriodDelegate = @TAccountingPeriodsWebConnector.GetFirstDayOfAccountingPeriod;

            TDBTransaction Transaction = null;
            bool SubmissionOK = false;

            DBAccess.GDBAccessObj.BeginAutoTransaction(IsolationLevel.Serializable,
                ref Transaction,
                ref SubmissionOK,
                delegate
                {
                    try
                    {
                        // Load supplementary tables that we are going to need for validation
                        ALedgerTable LedgerTable = ALedgerAccess.LoadByPrimaryKey(FLedgerNumber, Transaction);
                        AAccountTable AccountTable = AAccountAccess.LoadViaALedger(FLedgerNumber, Transaction);
                        ACostCentreTable CostCentreTable = ACostCentreAccess.LoadViaALedger(FLedgerNumber, Transaction);
                        AMotivationGroupTable MotivationGroupTable = AMotivationGroupAccess.LoadViaALedger(FLedgerNumber, Transaction);
                        AMotivationDetailTable MotivationDetailTable = AMotivationDetailAccess.LoadViaALedger(FLedgerNumber, Transaction);
                        AAccountPropertyTable AccountPropertyTable = AAccountPropertyAccess.LoadViaALedger(FLedgerNumber, Transaction);
                        AAccountingPeriodTable AccountingPeriodTable = AAccountingPeriodAccess.LoadViaALedger(FLedgerNumber, Transaction);
                        AMethodOfGivingTable MethodOfGivingTable = AMethodOfGivingAccess.LoadAll(Transaction);
                        AMethodOfPaymentTable MethodOfPaymentTable = AMethodOfPaymentAccess.LoadAll(Transaction);
                        ACurrencyTable CurrencyTable = ACurrencyAccess.LoadAll(Transaction);
                        PMailingTable MailingTable = PMailingAccess.LoadAll(Transaction);

                        if (LedgerTable.Rows.Count == 0)
                        {
                            throw new Exception(String.Format(Catalog.GetString("Ledger {0} doesn't exist."), FLedgerNumber));
                        }

                        string LedgerBaseCurrency = ((ALedgerRow)LedgerTable.Rows[0]).BaseCurrency;
                        string LedgerIntlCurrency = ((ALedgerRow)LedgerTable.Rows[0]).IntlCurrency;

                        ACorporateExchangeRateTable CorporateExchangeRateTable = ACorporateExchangeRateAccess.LoadViaACurrencyToCurrencyCode(
                            LedgerIntlCurrency,
                            Transaction);
                        ADailyExchangeRateTable DailyExchangeRateTable = ADailyExchangeRateAccess.LoadAll(Transaction);

                        ImportMessage = Catalog.GetString("Parsing first line");
                        AGiftRow previousGift = null;

                        // Go round a loop reading the file line by line
                        FImportLine = sr.ReadLine();
                        TValidationControlsDict EmptyControlsDict = new TValidationControlsDict();

                        while (FImportLine != null)
                        {
                            RowNumber++;

                            TextProcessedLength += (FImportLine.Length + FNewLine.Length);
                            PercentDone = 10 + ((TextProcessedLength * 90) / InitialTextLength);

                            // skip empty lines and commented lines
                            if ((FImportLine.Trim().Length > 0) && !FImportLine.StartsWith("/*") && !FImportLine.StartsWith("#"))
                            {
                                int numberOfElements = StringHelper.GetCSVList(FImportLine, FDelimiter).Count;

                                // Read the row analysisType - there is no 'validation' on this so we can make the call with null parameters
                                string RowType =
                                    TCommonImport.ImportString(ref FImportLine, FDelimiter, Catalog.GetString("row type"), null, RowNumber, Messages,
                                        null);

                                if (RowType == "B")
                                {
                                    ImportMessage = Catalog.GetString("Parsing a batch row");

                                    // It is a Batch row
                                    if (numberOfElements < 8)
                                    {
                                        Messages.Add(new TVerificationResult(String.Format(MCommonConstants.StrParsingErrorInLine, RowNumber),
                                                Catalog.GetString(
                                                    "Wrong number of batch columns.  The correct number is either 8 columns (in which case the gift type is assumed to be 'Gift') or 9 columns, which allows for alternative gift types."),
                                                TResultSeverity.Resv_Critical));

                                        FImportLine = sr.ReadLine();

                                        if (FImportLine != null)
                                        {
                                            TextProcessedLength += (FImportLine.Length + FNewLine.Length);
                                        }

                                        continue;
                                    }

                                    //Check if this is the start of a new batch (i.e. not the first batch)
                                    if ((previousGift != null) && (giftBatch != null))
                                    {
                                        //New batch so set total amount of Batch for previous batch
                                        giftBatch.BatchTotal = totalBatchAmount;
                                        intlRateFromBase = -1.0m;

                                        if (TVerificationHelper.IsNullOrOnlyNonCritical(Messages))
                                        {
                                            ImportMessage = Catalog.GetString("Saving batch");
                                            AGiftBatchAccess.SubmitChanges(FMainDS.AGiftBatch, Transaction);
                                            FMainDS.AGiftBatch.AcceptChanges();

                                            ImportMessage = Catalog.GetString("Saving gift");
                                            AGiftAccess.SubmitChanges(FMainDS.AGift, Transaction);
                                            FMainDS.AGift.AcceptChanges();

                                            ImportMessage = Catalog.GetString("Saving giftdetails");
                                            AGiftDetailAccess.SubmitChanges(FMainDS.AGiftDetail, Transaction);
                                            FMainDS.AGiftDetail.AcceptChanges();
                                        }

                                        previousGift = null;
                                    }

                                    ImportMessage = Catalog.GetString("Starting new batch");
                                    totalBatchAmount = 0;

                                    // Parse the complete line and validate it
                                    ParseBatchLine(ref giftBatch, ref Transaction, ref LedgerTable, ref ImportMessage, RowNumber, LedgerBaseCurrency,
                                        LedgerIntlCurrency, Messages,
                                        EmptyControlsDict, AccountTable, AccountPropertyTable, AccountingPeriodTable, CostCentreTable,
                                        CorporateExchangeRateTable, CurrencyTable);

                                    if (TVerificationHelper.IsNullOrOnlyNonCritical(Messages))
                                    {
                                        // This row passes validation so we can do final actions
                                        // Validation will have ensured that we have a corporate rate for intl currency
                                        // at least for the first day of the accounting period.
                                        // (There may possibly be others between then and the effective date)
                                        // We need to know what that rate is...
                                        DateTime firstOfMonth;

                                        if (TSharedFinanceValidationHelper.GetFirstDayOfAccountingPeriod(FLedgerNumber,
                                                giftBatch.GlEffectiveDate, out firstOfMonth))
                                        {
                                            intlRateFromBase =
                                                TExchangeRateTools.GetCorporateExchangeRate(LedgerBaseCurrency, LedgerIntlCurrency, firstOfMonth,
                                                    giftBatch.GlEffectiveDate);

                                            if (intlRateFromBase <= 0.0m)
                                            {
                                                // This should never happen (see above)
                                                Messages.Add(new TVerificationResult(String.Format(MCommonConstants.StrParsingErrorInLine, RowNumber),
                                                        String.Format(
                                                            "There is no Corporate Exchange Rate for {0} to {1} applicable to the period {2} to {3}.  Please set up an appropriate rate and then import the data again.",
                                                            LedgerBaseCurrency,
                                                            LedgerIntlCurrency,
                                                            StringHelper.DateToLocalizedString(firstOfMonth),
                                                            StringHelper.DateToLocalizedString(giftBatch.GlEffectiveDate)),
                                                        TResultSeverity.Resv_Critical));
                                            }
                                        }
                                    }

                                    if (TVerificationHelper.IsNullOrOnlyNonCritical(Messages))
                                    {
                                        // This row passes validation so we can do final actions
                                        // If the batch is not in the ledger currency we populate the Daily Exchange Rate table
                                        if (giftBatch.CurrencyCode != LedgerBaseCurrency)
                                        {
                                            ImportMessage = Catalog.GetString("Updating foreign exchange data");

                                            // we need to create a daily exchange rate pair for the transaction date
                                            // start with To Ledger currency
                                            if (UpdateDailyExchangeRateTable(DailyExchangeRateTable, giftBatch.CurrencyCode, LedgerBaseCurrency,
                                                    giftBatch.ExchangeRateToBase, giftBatch.GlEffectiveDate))
                                            {
                                                Messages.Add(new TVerificationResult(String.Format(MCommonConstants.StrImportInformationForLine,
                                                            RowNumber),
                                                        String.Format(Catalog.GetString(
                                                                "An exchange rate of {0} for '{1}' to '{2}' on {3} will be added to the Daily Exchange Rate table after a successful import."),
                                                            giftBatch.ExchangeRateToBase,
                                                            giftBatch.CurrencyCode,
                                                            LedgerBaseCurrency,
                                                            StringHelper.DateToLocalizedString(giftBatch.GlEffectiveDate)),
                                                        TResultSeverity.Resv_Info));
                                            }

                                            // Now the inverse for From Ledger currency
                                            decimal inverseRate = Math.Round(1 / giftBatch.ExchangeRateToBase, 10);

                                            UpdateDailyExchangeRateTable(DailyExchangeRateTable, LedgerBaseCurrency, giftBatch.CurrencyCode,
                                                inverseRate, giftBatch.GlEffectiveDate);
                                        }
                                    }
                                }
                                else if (RowType == "T")
                                {
                                    ImportMessage = Catalog.GetString("Parsing a transaction row");

                                    // It is a Transaction row
                                    if (numberOfElements < 13) // Perhaps this CSV file is a summary, and can't be imported?
                                    {
                                        Messages.Add(new TVerificationResult(String.Format(MCommonConstants.StrParsingErrorInLine, RowNumber),
                                                Catalog.GetString(
                                                    "Wrong number of gift columns. Expected at least 13 columns. (This may be a summary?)"),
                                                TResultSeverity.Resv_Critical));
                                        FImportLine = sr.ReadLine();

                                        if (FImportLine != null)
                                        {
                                            TextProcessedLength += (FImportLine.Length + FNewLine.Length);
                                        }

                                        continue;
                                    }

                                    if (giftBatch == null)
                                    {
                                        Messages.Add(new TVerificationResult(String.Format(MCommonConstants.StrParsingErrorInLine, RowNumber),
                                                Catalog.GetString(
                                                    "Expected a GiftBatch line, but found a Gift Transaction. Will create a dummy working batch for the current period."),
                                                TResultSeverity.Resv_Critical));

                                        // in order to carry on we will make a dummy batch and force the date to fit
                                        giftBatch = TGiftBatchFunctions.CreateANewGiftBatchRow(ref FMainDS,
                                            ref Transaction,
                                            ref LedgerTable,
                                            FLedgerNumber,
                                            DateTime.Today);
                                    }

                                    // Parse the line into a new row
                                    Int32 preParseMessageCount = Messages.Count;

                                    AGiftRow gift = FMainDS.AGift.NewRowTyped(true);
                                    AGiftDetailRow giftDetails = FMainDS.AGiftDetail.NewRowTyped(true);
                                    ParseTransactionLine(gift,
                                        giftBatch,
                                        ref previousGift,
                                        numberOfElements,
                                        ref totalBatchAmount,
                                        ref ImportMessage,
                                        RowNumber,
                                        intlRateFromBase,
                                        Messages,
                                        MotivationDetailTable,
                                        NeedRecipientLedgerNumber,
                                        giftDetails);

                                    if (Messages.Count == preParseMessageCount)     // No parsing errors so we can validate
                                    {                                               // (parsing errors will have assumed, probably invalid, values)
                                        ImportMessage = Catalog.GetString("Validating the gift data");

                                        int messageCountBeforeValidate = preParseMessageCount;

                                        TPartnerClass RecipientClass;
                                        string RecipientDescription;
                                        TPartnerServerLookups.GetPartnerShortName(giftDetails.RecipientKey, out RecipientDescription,
                                            out RecipientClass);

                                        // Do our standard validation on this gift
                                        AGiftValidation.Validate(this, gift, ref Messages, EmptyControlsDict);
                                        TSharedFinanceValidation_Gift.ValidateGiftManual(this, gift, giftBatch.BatchYear, giftBatch.BatchPeriod,
                                            null, ref Messages, EmptyControlsDict, MethodOfGivingTable, MethodOfPaymentTable);

                                        ImportMessage = Catalog.GetString("Validating the gift details data");

                                        AGiftDetailValidation.Validate(this, giftDetails, ref Messages, EmptyControlsDict);
                                        TSharedFinanceValidation_Gift.ValidateGiftDetailManual(this, (GiftBatchTDSAGiftDetailRow)giftDetails,
                                            ref Messages, EmptyControlsDict, RecipientClass, null, CostCentreTable, AccountTable,
                                            MotivationGroupTable, MotivationDetailTable, MailingTable, giftDetails.RecipientKey);

                                        // Fix up the messages
                                        for (int i = messageCountBeforeValidate; i < Messages.Count; i++)
                                        {
                                            ((TVerificationResult)Messages[i]).OverrideResultContext(String.Format(MCommonConstants.
                                                    StrValidationErrorInLine, RowNumber));

                                            if (Messages[i] is TScreenVerificationResult)
                                            {
                                                TVerificationResult downgrade = new TVerificationResult((TScreenVerificationResult)Messages[i]);
                                                Messages.RemoveAt(i);
                                                Messages.Insert(i, downgrade);
                                            }
                                        }
                                    }

                                    if (TaxDeductiblePercentageEnabled)
                                    {
                                        // Sets TaxDeductiblePct and uses it to calculate the tax deductibility amounts for a Gift Detail
                                        TGift.SetDefaultTaxDeductibilityData(ref giftDetails, gift.DateEntered, Transaction);
                                    }

                                    if (TVerificationHelper.IsNullOrOnlyNonCritical(Messages))
                                    {
                                        if ((LedgerBaseCurrency != LedgerIntlCurrency) && (giftDetails.GiftAmountIntl != 0))
                                        {
                                            // Check if the intl amount is what we expected
                                            if (giftDetails.GiftAmountIntl != GLRoutines.Divide(giftDetails.GiftAmount, intlRateFromBase, 2))
                                            {
                                                ImportMessage = Catalog.GetString("Updating international exchange rate data");

                                                // The import has used an intl rate that is different from the corporate rate
                                                //   so we should add a Daily Exchange Rate row pair
                                                // start with To Ledger currency
                                                decimal fromIntlToBase = GLRoutines.Divide(giftDetails.GiftAmount, giftDetails.GiftAmountIntl);

                                                if (UpdateDailyExchangeRateTable(DailyExchangeRateTable, LedgerIntlCurrency, LedgerBaseCurrency,
                                                        fromIntlToBase, giftBatch.GlEffectiveDate))
                                                {
                                                    Messages.Add(new TVerificationResult(String.Format(MCommonConstants.StrImportInformationForLine,
                                                                RowNumber),
                                                            String.Format(Catalog.GetString(
                                                                    "An exchange rate of {0} for '{1}' to '{2}' on {3} will be added to the Daily Exchange Rate table after a successful import."),
                                                                fromIntlToBase, StringHelper.DateToLocalizedString(giftBatch.GlEffectiveDate)),
                                                            TResultSeverity.Resv_Info));
                                                }

                                                // Now the inverse for From Ledger currency
                                                decimal inverseRate = GLRoutines.Divide(giftDetails.GiftAmountIntl, giftDetails.GiftAmount);

                                                UpdateDailyExchangeRateTable(DailyExchangeRateTable, LedgerBaseCurrency, LedgerIntlCurrency,
                                                    inverseRate, giftBatch.GlEffectiveDate);
                                            }
                                        }
                                    }
                                } // If known row analysisType
                                else
                                {
                                    if (giftBatch == null)
                                    {
                                        string msg = Catalog.GetString(
                                            "Expecting a Row Type definition. Valid types are 'B' or 'T'. Maybe you are opening a 'Transactions' file.");
                                        msg +=
                                            Catalog.GetString(
                                                "  You need to be on the 'Transactions' Tab to import transaction-only data into an existing batch.");
                                        msg += Catalog.GetString("  Alternatively you may have selected the wrong Field Delimiter.");
                                        msg += Catalog.GetString("  Choose a delimiter that shows multiple columns in the preview window.");
                                        Messages.Add(new TVerificationResult(String.Format(MCommonConstants.StrParsingErrorInLine, RowNumber),
                                                msg,
                                                TResultSeverity.Resv_Critical));
                                        break;
                                    }
                                    else
                                    {
                                        Messages.Add(new TVerificationResult(String.Format(MCommonConstants.StrParsingErrorInLine, RowNumber),
                                                String.Format(Catalog.GetString(
                                                        "'{0}' is not a valid Row Type. Valid types are 'B' or 'T'."),
                                                    RowType), TResultSeverity.Resv_Critical));
                                    }
                                }
                            }  // if the CSV line qualifies

                            if (TProgressTracker.GetCurrentState(DomainManager.GClientID.ToString()).CancelJob == true)
                            {
                                CancelledByUser = true;
                                break;
                            }

                            if (Messages.Count > 100)
                            {
                                // This probably means that it is a big file and the user has made the same mistake many times over
                                break;
                            }

                            // Update progress tracker every few percent
                            if ((PercentDone - PreviousPercentDone) > 3)
                            {
                                TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                                    String.Format(Catalog.GetString("Importing row {0}"), RowNumber),
                                    (PercentDone > 98) ? 98 : PercentDone);
                                PreviousPercentDone = PercentDone;
                            }

                            // Read the next line
                            FImportLine = sr.ReadLine();

                            if (FImportLine != null)
                            {
                                TextProcessedLength += (FImportLine.Length + FNewLine.Length);
                            }
                        }  // while CSV lines

                        if (CancelledByUser)
                        {
                            Messages.Add(new TVerificationResult(MCommonConstants.StrImportInformation,
                                    String.Format(Catalog.GetString("{0} messages reported."), Messages.Count), TResultSeverity.Resv_Info));
                            Messages.Add(new TVerificationResult(MCommonConstants.StrImportInformation,
                                    "The import was cancelled by the user.", TResultSeverity.Resv_Info));
                            return;
                        }

                        // Finished reading the file - did we have critical errors?
                        if (!TVerificationHelper.IsNullOrOnlyNonCritical(Messages))
                        {
                            TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                                Catalog.GetString("Batch has critical errors"),
                                0);

                            // Record error count
                            Messages.Add(new TVerificationResult(MCommonConstants.StrImportInformation,
                                    String.Format(Catalog.GetString("{0} messages reported."), Messages.Count), TResultSeverity.Resv_Info));

                            if (FImportLine == null)
                            {
                                // We did reach the end of the file
                                Messages.Add(new TVerificationResult(MCommonConstants.StrImportInformation,
                                        Catalog.GetString(
                                            "Reached the end of file but errors occurred. When these errors are fixed the batch will import successfully."),
                                        TResultSeverity.Resv_Info));
                            }
                            else
                            {
                                // We gave up before the end
                                if (Messages.Count > 100)
                                {
                                    Messages.Add(new TVerificationResult(MCommonConstants.StrImportInformation,
                                            Catalog.GetString(
                                                "Stopped reading the file after generating more than 100 messages.  The file may contian more errors beyond the ones listed here."),
                                            TResultSeverity.Resv_Info));
                                }
                                else
                                {
                                    Messages.Add(new TVerificationResult(MCommonConstants.StrImportInformation,
                                            Catalog.GetString(
                                                "Stopped reading the file. Please check you are using a Gift Batch Import file and have chosen the correct Field Delimiter."),
                                            TResultSeverity.Resv_Info));
                                }
                            }

                            // we do not want to think about Gift Destination problems if the import has failed for another reason
                            NeedRecipientLedgerNumber.Clear();

                            // Do the 'finally' actions and return false
                            return;
                        }

                        // if the import contains gifts with Motivation Group 'GIFT' and that have a Family recipient with no Gift Destination then the import will fail
                        if (NeedRecipientLedgerNumber.Rows.Count > 0)
                        {
                            return;
                        }

                        // Everything is ok, so we can do our finish actions

                        //Update batch total for the last batch entered.
                        if (giftBatch != null)
                        {
                            giftBatch.BatchTotal = totalBatchAmount;
                        }

                        ImportMessage = Catalog.GetString("Saving all data into the database");

                        //Finally save pending changes (the last number is updated !)
                        ImportMessage = Catalog.GetString("Saving daily exchange rates");
                        ADailyExchangeRateAccess.SubmitChanges(DailyExchangeRateTable, Transaction);
                        DailyExchangeRateTable.AcceptChanges();

                        ImportMessage = Catalog.GetString("Saving final batch");
                        AGiftBatchAccess.SubmitChanges(FMainDS.AGiftBatch, Transaction);
                        FMainDS.AGiftBatch.AcceptChanges();

                        ImportMessage = Catalog.GetString("Saving final gift");
                        AGiftAccess.SubmitChanges(FMainDS.AGift, Transaction);
                        FMainDS.AGift.AcceptChanges();

                        ImportMessage = Catalog.GetString("Saving final giftdetails");
                        AGiftDetailAccess.SubmitChanges(FMainDS.AGiftDetail, Transaction);
                        FMainDS.AGiftDetail.AcceptChanges();

                        ImportMessage = Catalog.GetString("Saving ledger changes");
                        ALedgerAccess.SubmitChanges(LedgerTable, Transaction);
                        FMainDS.ALedger.AcceptChanges();

                        // Commit the transaction (we know that we got a new one and can control it)
                        SubmissionOK = true;
                    }
                    catch (Exception ex)
                    {
                        // Parse the exception text for possible references to database foreign keys
                        // Make the message more friendly in that case
                        string friendlyExceptionText = MakeFriendlyFKExceptions(ex);

                        if (RowNumber > 0)
                        {
                            // At least we made a start
                            string msg = ImportMessage;

                            if (friendlyExceptionText.Length > 0)
                            {
                                msg += FNewLine + friendlyExceptionText;
                            }

                            if (ImportMessage.StartsWith(Catalog.GetString("Saving ")))
                            {
                                // Do not display any specific line number because these errors occur outside the parsing loop
                                Messages.Add(new TVerificationResult(String.Format(MCommonConstants.StrExceptionWhileSavingBatch,
                                            giftBatch.BatchDescription),
                                        msg, TResultSeverity.Resv_Critical));
                            }
                            else
                            {
                                Messages.Add(new TVerificationResult(String.Format(MCommonConstants.StrExceptionWhileParsingLine, RowNumber),
                                        msg, TResultSeverity.Resv_Critical));
                            }
                        }
                        else
                        {
                            // We got an exception before we even started parsing the rows (getting a transaction?)
                            Messages.Add(new TVerificationResult(String.Format(MCommonConstants.StrExceptionWhileParsingLine, RowNumber),
                                    friendlyExceptionText, TResultSeverity.Resv_Critical));
                        }

                        TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                            Catalog.GetString("Exception Occurred"),
                            0);

                        SubmissionOK = false;
                    }
                    finally
                    {
                        sr.Close();

                        if (SubmissionOK)
                        {
                            TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                                Catalog.GetString("Gift batch import successful"),
                                100);
                        }
                        else
                        {
                            Messages.Add(new TVerificationResult(MCommonConstants.StrImportInformation,
                                    Catalog.GetString("None of the data from the import was saved."),
                                    TResultSeverity.Resv_Critical));

                            TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                                Catalog.GetString("Data could not be saved."),
                                0);
                        }

                        TProgressTracker.FinishJob(DomainManager.GClientID.ToString());
                    } // end of 'finally'
                });

            // Set our 'out' parameters
            AMessages = Messages;
            ANeedRecipientLedgerNumber = NeedRecipientLedgerNumber;

            return SubmissionOK;
        }
Example #16
0
        /// <summary>
        /// This "Einzahlungsschein mit Referenznummer" (ESR) input format is only used in Switzerland.
        /// This method could be pulled out of here, but sits here quite nicely.
        /// </summary>
        /// <param name="AImportLine"></param>
        /// <param name="AgiftBatch"></param>
        /// <param name="Agift"></param>
        /// <param name="AgiftDetails"></param>
        /// <param name="AIntlRateToBase"></param>
        /// <param name="AMotivationDetailTable"></param>
        /// <param name="ANeedRecipientLedgerNumber"></param>
        /// <param name="AMessages"></param>
        /// <returns></returns>
        private Boolean ParseEsrTransactionLine(
            String AImportLine,
            AGiftBatchRow AgiftBatch,
            AGiftRow Agift,
            AGiftDetailRow AgiftDetails,
            Decimal AIntlRateToBase,
            AMotivationDetailTable AMotivationDetailTable,
            GiftBatchTDSAGiftDetailTable ANeedRecipientLedgerNumber,
            TVerificationResultCollection AMessages
            )
        {
            Boolean NonNumericError = false;
            String Field = AImportLine.Substring(0, 3);

            Int32 FunctionType = 0;

            NonNumericError &= !Int32.TryParse(Field, out FunctionType);

            Int64 DonorKey = 0;
            Field = AImportLine.Substring(12, 10);
            NonNumericError &= !Int64.TryParse(Field, out DonorKey);

            Int64 RecipientKey = 0;
            Field = AImportLine.Substring(22, 10);
            NonNumericError &= !Int64.TryParse(Field, out RecipientKey);

            Int64 intAmount = 0;
            Field = AImportLine.Substring(39, 10);
            NonNumericError &= !Int64.TryParse(Field, out intAmount);

            Decimal Amount = intAmount / 100;

            if (NonNumericError)
            {
                return false;
            }

            String MotivGroup = "GIFT";
            String MotivDetail = "UNDESIG";
            TGuiTools.GetMotivationGroupAndDetail(RecipientKey, ref MotivGroup, ref MotivDetail);

            Agift.LedgerNumber = AgiftBatch.LedgerNumber;
            Agift.BatchNumber = AgiftBatch.BatchNumber;
            Agift.GiftTransactionNumber = AgiftBatch.LastGiftNumber + 1;
            AgiftBatch.LastGiftNumber++;
            AgiftBatch.BatchTotal += Amount;
            Agift.LastDetailNumber = 1;

            ExchangeFieldsInEsrTransaction(ref DonorKey, ref RecipientKey, AMessages, Agift.GiftTransactionNumber);

            Agift.DonorKey = DonorKey;
            Agift.MethodOfGivingCode = "DEFAULT";
            Agift.MethodOfPaymentCode = "ESR";
            FMainDS.AGift.Rows.Add(Agift);

            AgiftDetails.RecipientKey = RecipientKey;
            AgiftDetails.LedgerNumber = AgiftBatch.LedgerNumber;
            AgiftDetails.BatchNumber = AgiftBatch.BatchNumber;
            AgiftDetails.GiftTransactionNumber = Agift.GiftTransactionNumber;
            AgiftDetails.DetailNumber = 1;
            AgiftDetails.GiftTransactionAmount = Amount;
            AgiftDetails.GiftAmount = GLRoutines.Divide(Amount, AgiftBatch.ExchangeRateToBase);      // amount in ledger currency

            if (AIntlRateToBase > 0.0m)
            {
                AgiftDetails.GiftAmountIntl = GLRoutines.Divide(AgiftDetails.GiftAmount, AIntlRateToBase, 2);
            }

            AgiftDetails.RecipientLedgerNumber = TGiftTransactionWebConnector.GetRecipientFundNumber(AgiftDetails.RecipientKey,
                AgiftBatch.GlEffectiveDate);


            AgiftDetails.MotivationGroupCode = MotivGroup;
            AgiftDetails.MotivationDetailCode = MotivDetail;
            AgiftDetails.CostCentreCode = TGiftTransactionWebConnector.RetrieveCostCentreCodeForRecipient(
                AgiftDetails.LedgerNumber, AgiftDetails.RecipientKey, AgiftDetails.RecipientLedgerNumber,
                Agift.DateEntered, AgiftDetails.MotivationGroupCode, AgiftDetails.MotivationDetailCode);

            AMotivationDetailRow motivationDetailRow = (AMotivationDetailRow)AMotivationDetailTable.Rows.Find(
                new object[] { FLedgerNumber, AgiftDetails.MotivationGroupCode, AgiftDetails.MotivationDetailCode });

            // Account Code is inferred from the motivation detail.
            Boolean IsTaxDeductible = false;
            string NewAccountCode = null;
            string NewTaxDeductibleAccountCode = null;

            if (motivationDetailRow != null)
            {
                IsTaxDeductible = motivationDetailRow.TaxDeductible;
                NewAccountCode = motivationDetailRow.AccountCode;
                NewTaxDeductibleAccountCode = motivationDetailRow.TaxDeductibleAccountCode;
            }

            AgiftDetails.TaxDeductible = IsTaxDeductible;
            AgiftDetails.AccountCode = NewAccountCode;
            AgiftDetails.TaxDeductibleAccountCode = NewTaxDeductibleAccountCode;

            // If the gift has a recipient with no Gift Destination then the import will fail. Gift is added to a table and returned to client.
            if ((AgiftDetails.RecipientLedgerNumber == 0) && (AgiftDetails.MotivationGroupCode == MFinanceConstants.MOTIVATION_GROUP_GIFT))
            {
                ((GiftBatchTDSAGiftDetailRow)AgiftDetails).RecipientDescription = "Fault: RecipientLedger Not known";
                ANeedRecipientLedgerNumber.Rows.Add((object[])AgiftDetails.ItemArray.Clone());
            }

            FMainDS.AGiftDetail.Rows.Add(AgiftDetails);
            return true;
        }
        /// <summary>
        /// Import a transactions file or a clipboard equivalent
        /// </summary>
        /// <param name="ACurrentBatchRow">The batch to import to</param>
        /// <param name="AImportSource">The import source - eg File or Clipboard</param>
        /// <returns>True if the import was successful</returns>
        public bool ImportTransactions(AGiftBatchRow ACurrentBatchRow, TGiftImportDataSourceEnum AImportSource)
        {
            bool ok = false;
            String importString;
            String impOptions;
            OpenFileDialog dialog = null;

            if (FPetraUtilsObject.HasChanges)
            {
                // saving failed, therefore do not try to import
                MessageBox.Show(Catalog.GetString("Please save before calling this function!"), Catalog.GetString(
                        "Gift Import"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            if ((ACurrentBatchRow == null) || (ACurrentBatchRow.BatchStatus != MFinanceConstants.BATCH_UNPOSTED))
            {
                MessageBox.Show(Catalog.GetString("Please select an unposted batch to import transactions."), Catalog.GetString(
                        "Gift Import"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            if (ACurrentBatchRow.LastGiftNumber > 0)
            {
                if (MessageBox.Show(Catalog.GetString(
                            "The current batch already contains some gift transactions.  Do you really want to add more transactions to this batch?"),
                        Catalog.GetString("Gift Transaction Import"),
                        MessageBoxButtons.YesNo,
                        MessageBoxIcon.Question,
                        MessageBoxDefaultButton.Button2) == DialogResult.No)
                {
                    return false;
                }
            }

            FdlgSeparator = new TDlgSelectCSVSeparator(false);

            if (AImportSource == TGiftImportDataSourceEnum.FromClipboard)
            {
                importString = Clipboard.GetText(TextDataFormat.UnicodeText);

                if ((importString == null) || (importString.Length == 0))
                {
                    MessageBox.Show(Catalog.GetString("Please first copy data from your spreadsheet application!"),
                        Catalog.GetString("Failure"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return false;
                }

                impOptions = TUserDefaults.GetStringDefault("Imp Options", ";American");
                String dateFormatString = TUserDefaults.GetStringDefault("Imp Date", "MDY");
                FdlgSeparator = new TDlgSelectCSVSeparator(false);
                FdlgSeparator.SelectedSeparator = "\t";
                FdlgSeparator.CSVData = importString;
                FdlgSeparator.DateFormat = dateFormatString;

                if (impOptions.Length > 1)
                {
                    FdlgSeparator.NumberFormat = impOptions.Substring(1);
                }
            }
            else if (AImportSource == TGiftImportDataSourceEnum.FromFile)
            {
                dialog = new OpenFileDialog();

                dialog.FileName = TUserDefaults.GetStringDefault("Imp Filename",
                    TClientSettings.GetExportPath() + Path.DirectorySeparatorChar + "import.csv");

                dialog.Title = Catalog.GetString("Import Transactions from CSV File");
                dialog.Filter = Catalog.GetString("Gift Transactions files (*.csv)|*.csv");
                impOptions = TUserDefaults.GetStringDefault("Imp Options", ";" + TDlgSelectCSVSeparator.NUMBERFORMAT_AMERICAN);

                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    Boolean fileCanOpen = FdlgSeparator.OpenCsvFile(dialog.FileName);

                    if (!fileCanOpen)
                    {
                        MessageBox.Show(Catalog.GetString("Unable to open file."),
                            Catalog.GetString("Gift Import"),
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Stop);
                        return false;
                    }

                    importString = File.ReadAllText(dialog.FileName);

                    String dateFormatString = TUserDefaults.GetStringDefault("Imp Date", "MDY");
                    FdlgSeparator.DateFormat = dateFormatString;

                    if (impOptions.Length > 1)
                    {
                        FdlgSeparator.NumberFormat = impOptions.Substring(1);
                    }

                    FdlgSeparator.SelectedSeparator = impOptions.Substring(0, 1);
                }
                else
                {
                    return false;
                }
            }
            else
            {
                // unknown source!!  The following need a value...
                impOptions = String.Empty;
                importString = String.Empty;
            }

            if (FdlgSeparator.ShowDialog() == DialogResult.OK)
            {
                Hashtable requestParams = new Hashtable();

                requestParams.Add("ALedgerNumber", FLedgerNumber);
                requestParams.Add("Delimiter", FdlgSeparator.SelectedSeparator);
                requestParams.Add("DateFormatString", FdlgSeparator.DateFormat);
                requestParams.Add("NumberFormat", FdlgSeparator.NumberFormat);
                requestParams.Add("NewLine", Environment.NewLine);

                bool Repeat = true;

                while (Repeat)
                {
                    Repeat = false;

                    TVerificationResultCollection AMessages = new TVerificationResultCollection();
                    GiftBatchTDSAGiftDetailTable NeedRecipientLedgerNumber = new GiftBatchTDSAGiftDetailTable();

                    Thread ImportThread = new Thread(() => ImportGiftTransactions(
                            requestParams,
                            importString,
                            ACurrentBatchRow.BatchNumber,
                            out AMessages,
                            out ok,
                            out NeedRecipientLedgerNumber));

                    using (TProgressDialog ImportDialog = new TProgressDialog(ImportThread))
                    {
                        ImportDialog.ShowDialog();
                    }

                    ShowMessages(AMessages);

                    // if the import contains gifts with Motivation Group 'GIFT' and that have a Family recipient with no Gift Destination
                    // then the import will have failed and we need to alert the user
                    if (NeedRecipientLedgerNumber.Rows.Count > 0)
                    {
                        bool OfferToRunImportAgain = true;

                        // for each gift in which the recipient needs a Git Destination
                        foreach (GiftBatchTDSAGiftDetailRow Row in NeedRecipientLedgerNumber.Rows)
                        {
                            if (MessageBox.Show(string.Format(
                                        Catalog.GetString(
                                            "Gift Import has been cancelled as the recipient '{0}' ({1}) has no Gift Destination assigned."),
                                        Row.RecipientDescription, Row.RecipientKey) +
                                    "\n\n" +
                                    Catalog.GetString("Do you want to assign a Gift Destination to this partner now?"),
                                    Catalog.GetString("Gift Import"), MessageBoxButtons.YesNo, MessageBoxIcon.Warning)
                                == DialogResult.Yes)
                            {
                                // allow the user to assign a Gift Destingation
                                TFrmGiftDestination GiftDestinationForm = new TFrmGiftDestination(FPetraUtilsObject.GetForm(), Row.RecipientKey);
                                GiftDestinationForm.ShowDialog();
                            }
                            else
                            {
                                OfferToRunImportAgain = false;
                            }
                        }

                        // if the user has clicked yes to assigning Gift Destinations then offer to restart the import
                        if (OfferToRunImportAgain
                            && (MessageBox.Show(Catalog.GetString("Would you like to import these Gift Transactions again?"),
                                    Catalog.GetString("Gift Import"), MessageBoxButtons.YesNo, MessageBoxIcon.Question,
                                    MessageBoxDefaultButton.Button1)
                                == DialogResult.Yes))
                        {
                            Repeat = true;
                        }
                    }
                }
            }

            if (ok)
            {
                MessageBox.Show(Catalog.GetString("Your data was imported successfully!"),
                    Catalog.GetString("Gift Import"),
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);

                SaveUserDefaults(dialog, impOptions);
                //FMyUserControl.LoadBatchesForCurrentYear();
                FPetraUtilsObject.DisableSaveButton();
            }

            return ok;
        }
        /// <summary>
        /// Wrapper method to handle returned bool value from remoting call to ImportGiftTransactions
        /// </summary>
        /// <param name="ARequestParams"></param>
        /// <param name="AImportString"></param>
        /// <param name="ABatchNumber"></param>
        /// <param name="AMessages"></param>
        /// <param name="ok"></param>
        /// <param name="ANeedRecipientLedgerNumber"></param>
        private void ImportGiftTransactions(Hashtable ARequestParams, string AImportString, Int32 ABatchNumber,
            out TVerificationResultCollection AMessages, out bool ok, out GiftBatchTDSAGiftDetailTable ANeedRecipientLedgerNumber)
        {
            TVerificationResultCollection AResultMessages;
            bool ImportIsSuccessful;

            ImportIsSuccessful = TRemote.MFinance.Gift.WebConnectors.ImportGiftTransactions(
                ARequestParams,
                AImportString,
                ABatchNumber,
                out ANeedRecipientLedgerNumber,
                out AResultMessages);

            ok = ImportIsSuccessful;
            AMessages = AResultMessages;
        }
        /// <summary>
        /// Main method to post a specified batch
        /// </summary>
        /// <param name="ACurrentBatchRow">The batch row to post</param>
        /// <returns>True if the batch was successfully posted</returns>
        public bool PostBatch(AGiftBatchRow ACurrentBatchRow)
        {
            if ((ACurrentBatchRow == null) || (ACurrentBatchRow.BatchStatus != MFinanceConstants.BATCH_UNPOSTED))
            {
                return(false);
            }

            FSelectedBatchNumber = ACurrentBatchRow.BatchNumber;
            TVerificationResultCollection Verifications;

            try
            {
                FMyForm.EnsureGiftDataPresent(FLedgerNumber, FSelectedBatchNumber);

                GiftBatchTDSAGiftDetailTable BatchGiftDetails = new GiftBatchTDSAGiftDetailTable();

                foreach (GiftBatchTDSAGiftDetailRow Row in FMainDS.AGiftDetail.Rows)
                {
                    if (Row.BatchNumber == FSelectedBatchNumber)
                    {
                        BatchGiftDetails.Rows.Add((object[])Row.ItemArray.Clone());
                    }
                }

                // there are no gifts in this batch!
                if (BatchGiftDetails.Rows.Count == 0)
                {
                    FMyForm.Cursor = Cursors.Default;
                    MessageBox.Show(Catalog.GetString("Batch is empty!"), Catalog.GetString("Posting failed"),
                                    MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    return(false);
                }

                bool CancelledDueToExWorkerOrAnonDonor;

                // save first, then post
                if (!FMyForm.SaveChangesForPosting(BatchGiftDetails, out CancelledDueToExWorkerOrAnonDonor))
                {
                    FMyForm.Cursor = Cursors.Default;

                    if (!CancelledDueToExWorkerOrAnonDonor)
                    {
                        // saving failed, therefore do not try to post
                        MessageBox.Show(Catalog.GetString("The batch was not posted due to problems during saving; ") + Environment.NewLine +
                                        Catalog.GetString("Please first correct and save the batch, and then post it!"));
                    }

                    return(false);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            //Check for missing international exchange rate
            bool IsTransactionInIntlCurrency = false;

            if (FMyForm.InternationalCurrencyExchangeRate(ACurrentBatchRow, out IsTransactionInIntlCurrency, true) == 0)
            {
                return(false);
            }

            //Check for inactive KeyMinistries
            DataTable GiftsWithInactiveKeyMinistries;

            if (TRemote.MFinance.Gift.WebConnectors.InactiveKeyMinistriesFoundInBatch(FLedgerNumber, FSelectedBatchNumber,
                                                                                      out GiftsWithInactiveKeyMinistries))
            {
                string listOfOffendingRows = "Gift   Detail   Recipient        KeyMinistry" + Environment.NewLine;
                listOfOffendingRows += "------------------------------------------------";

                foreach (DataRow dr in GiftsWithInactiveKeyMinistries.Rows)
                {
                    listOfOffendingRows += String.Format("{0}{1:0000}    {2:00}    {3:00000000000}    {4}",
                                                         Environment.NewLine,
                                                         dr[0],
                                                         dr[1],
                                                         dr[2],
                                                         dr[3]);
                }

                string msg = String.Format(Catalog.GetString("Cannot post Batch {0} as inactive Key Ministries found in gifts:{1}{1}{2}"),
                                           FSelectedBatchNumber,
                                           Environment.NewLine,
                                           listOfOffendingRows);

                MessageBox.Show(msg, Catalog.GetString("Inactive Key Ministries Found"));

                return(false);
            }

            // ask if the user really wants to post the batch
            if (MessageBox.Show(String.Format(Catalog.GetString("Do you really want to post gift batch {0}?"),
                                              FSelectedBatchNumber),
                                Catalog.GetString("Confirm posting of Gift Batch"),
                                MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
            {
                return(false);
            }

            Verifications = new TVerificationResultCollection();

            try
            {
                FPostingInProgress = true;

                Thread postingThread = new Thread(() => PostGiftBatch(out Verifications));

                using (TProgressDialog dialog = new TProgressDialog(postingThread))
                {
                    dialog.ShowDialog();
                }

                if (!TVerificationHelper.IsNullOrOnlyNonCritical(Verifications))
                {
                    string ErrorMessages = String.Empty;

                    foreach (TVerificationResult verif in Verifications)
                    {
                        ErrorMessages += "[" + verif.ResultContext + "] " +
                                         verif.ResultTextCaption + ": " +
                                         verif.ResultText + Environment.NewLine;
                    }

                    System.Windows.Forms.MessageBox.Show(ErrorMessages, Catalog.GetString("Posting failed"));
                }
                else
                {
                    MessageBox.Show(Catalog.GetString("The batch has been posted successfully!"));

                    return(true);
                }
            }
            catch (Exception ex)
            {
                string msg = (String.Format(Catalog.GetString("Unexpected error occurred during the posting of a Gift Batch!{0}{1}{2}{1}    {3}"),
                                            Utilities.GetMethodSignature(),
                                            Environment.NewLine,
                                            ex.Message,
                                            ex.InnerException.Message));

                TLogging.Log(msg);
                throw ex;
                //MessageBox.Show(msg, "Post Gift Batch Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                FPostingInProgress = false;
            }

            return(false);
        }
Example #20
0
        /// <summary>
        /// Looks for gifts where the recipient is an ExWorker and asks the user if they want to continue.
        /// (Make sure GetDataFromControls is called before this method so that AMainDS is up-to-date.)
        /// </summary>
        /// <param name="AAction">Why this method is being called</param>
        /// <param name="AMainDS"></param>
        /// <param name="APetraUtilsObject"></param>
        /// <param name="APostingGiftDetails">Only used when being called in order to carry out a batch posting</param>
        /// <returns>Returns true if saving/posting can continue</returns>
        public static bool CanContinueWithAnyExWorkers(GiftBatchAction AAction,
                                                       GiftBatchTDS AMainDS,
                                                       TFrmPetraEditUtils APetraUtilsObject,
                                                       DataTable APostingGiftDetails = null)
        {
            DataTable ExWorkers     = null;
            string    Msg           = string.Empty;
            int       BatchNumber   = -1;
            int       ExWorkerGifts = 0;

            string ExWorkerSpecialType = TSystemDefaults.GetStringDefault(SharedConstants.SYSDEFAULT_EXWORKERSPECIALTYPE, "EX-WORKER");

            // first check for Ex-Workers in the batch that is being posted/submitted (if a batch is being posted/submitted)
            if ((APostingGiftDetails != null) && (APostingGiftDetails.Rows.Count > 0))
            {
                ExWorkers      = TRemote.MFinance.Gift.WebConnectors.FindGiftRecipientExWorker(APostingGiftDetails, BatchNumber);
                ExWorkerGifts += ExWorkers.Rows.Count;

                Msg = GetExWorkersString(AAction, ExWorkerSpecialType, ExWorkers);

                if (ExWorkers.Rows.Count > 0)
                {
                    BatchNumber = (int)APostingGiftDetails.Rows[0][GiftBatchTDSAGiftDetailTable.GetBatchNumberDBName()];
                }
            }

            // check for Ex-Workers in all added and modified data
            if (APetraUtilsObject.HasChanges)
            {
                DataTable Changes = new DataTable();

                if (AMainDS.AGiftDetail.GetChangesTyped() != null)
                {
                    Changes.Merge(AMainDS.AGiftDetail.GetChangesTyped());
                }
                else if (AMainDS.ARecurringGiftDetail.GetChangesTyped() != null)
                {
                    Changes.Merge(AMainDS.ARecurringGiftDetail.GetChangesTyped());
                }

                if ((Changes != null) && (Changes.Rows.Count > 0))
                {
                    ExWorkers      = TRemote.MFinance.Gift.WebConnectors.FindGiftRecipientExWorker(Changes, BatchNumber);
                    ExWorkerGifts += ExWorkers.Rows.Count;

                    Msg += GetExWorkersString(null, ExWorkerSpecialType, ExWorkers);
                }
            }

            // alert the user to any recipients who are Ex-Workers
            if (Msg != string.Empty)
            {
                if (AAction == GiftBatchAction.SAVING)
                {
                    Msg += Environment.NewLine + Environment.NewLine;
                    Msg += Catalog.GetString("Do you want to continue with saving anyway?");
                }
                else
                {
                    Msg += Environment.NewLine + Environment.NewLine;
                    Msg += Catalog.GetString("(any changes will also need to be saved before ");

                    if (AAction == GiftBatchAction.NEWBATCH)
                    {
                        Msg += Catalog.GetString("a new batch can be created");
                    }
                    else //POSTING, CANCELLING, SUBMITTING, DELETING
                    {
                        Msg += Catalog.GetString("this batch continues with " + AAction.ToString().ToLower());
                    }

                    Msg += ")" + Environment.NewLine + Environment.NewLine;
                    Msg += Catalog.GetString("Do you want to continue?");
                }

                TFrmExtendedMessageBox extendedMessageBox = new TFrmExtendedMessageBox(APetraUtilsObject.GetForm());

                if (extendedMessageBox.ShowDialog(Msg,
                                                  Catalog.GetString("Ex-Workers Found"), string.Empty,
                                                  TFrmExtendedMessageBox.TButtons.embbYesNo,
                                                  TFrmExtendedMessageBox.TIcon.embiWarning)
                    == TFrmExtendedMessageBox.TResult.embrNo)
                {
                    return(false);
                }
            }

            return(true);
        }
Example #21
0
        /// <summary>
        /// this supports the batch export files from Petra 2.x.
        /// Each line starts with a type specifier, B for batch, J for journal, T for transaction
        /// </summary>
        public void ImportBatches(TGiftImportDataSourceEnum AImportSource, GiftBatchTDS AMainDS)
        {
            bool           ImportOK = false;
            bool           RefreshGUIAfterImport = false;
            OpenFileDialog OFileDialog           = null;

            if (FPetraUtilsObject.HasChanges)
            {
                // saving failed, therefore do not try to import
                MessageBox.Show(Catalog.GetString("Please save before calling this function!"), Catalog.GetString(
                                    "Failure"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            ALedgerRow LedgerRow             = (ALedgerRow)AMainDS.ALedger.Rows[0];
            int        CurrentTopBatchNumber = LedgerRow.LastGiftBatchNumber;

            try
            {
                FMyForm.FCurrentGiftBatchAction = Logic.TExtraGiftBatchChecks.GiftBatchAction.IMPORTING;

                bool datesMayBeIntegers = TUserDefaults.GetBooleanDefault(MCommonConstants.USERDEFAULT_IMPORTEDDATESMAYBEINTEGERS, false);
                FdlgSeparator = new TDlgSelectCSVSeparator(false);
                FdlgSeparator.DateMayBeInteger = datesMayBeIntegers;

                if (AImportSource == TGiftImportDataSourceEnum.FromClipboard)
                {
                    string ImportString = Clipboard.GetText(TextDataFormat.UnicodeText);

                    if ((ImportString == null) || (ImportString.Length == 0))
                    {
                        MessageBox.Show(Catalog.GetString("Please first copy data from your spreadsheet application!"),
                                        Catalog.GetString("Failure"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }

                    FdlgSeparator.CSVData = ImportString;
                }
                else if (AImportSource == TGiftImportDataSourceEnum.FromFile)
                {
                    OFileDialog = new OpenFileDialog();

                    string exportPath = TClientSettings.GetExportPath();
                    string fullPath   = TUserDefaults.GetStringDefault("Imp Filename",
                                                                       exportPath + Path.DirectorySeparatorChar + "import.csv");
                    TImportExportDialogs.SetOpenFileDialogFilePathAndName(OFileDialog, fullPath, exportPath);

                    OFileDialog.Title  = Catalog.GetString("Import Batches from CSV File");
                    OFileDialog.Filter = Catalog.GetString("Gift Batch Files(*.csv)|*.csv|Text Files(*.txt)|*.txt");

                    // This call fixes Windows7 Open File Dialogs.  It must be the line before ShowDialog()
                    TWin7FileOpenSaveDialog.PrepareDialog(Path.GetFileName(fullPath));

                    if (OFileDialog.ShowDialog() == DialogResult.OK)
                    {
                        Boolean fileCanOpen = FdlgSeparator.OpenCsvFile(OFileDialog.FileName);

                        if (!fileCanOpen)
                        {
                            MessageBox.Show(Catalog.GetString("Unable to open file."),
                                            Catalog.GetString("Gift Import"),
                                            MessageBoxButtons.OK,
                                            MessageBoxIcon.Stop);
                            return;
                        }
                    }
                    else
                    {
                        return;
                    }
                }
                else
                {
                    // unknown source!!
                    return;
                }

                String impOptions       = TUserDefaults.GetStringDefault("Imp Options", ";" + TDlgSelectCSVSeparator.NUMBERFORMAT_AMERICAN);
                String dateFormatString = TUserDefaults.GetStringDefault("Imp Date", "MDY");

                FdlgSeparator.DateFormat        = dateFormatString;
                FdlgSeparator.NumberFormat      = (impOptions.Length > 1) ? impOptions.Substring(1) : TDlgSelectCSVSeparator.NUMBERFORMAT_AMERICAN;
                FdlgSeparator.SelectedSeparator = StringHelper.GetCSVSeparator(FdlgSeparator.FileContent) ??
                                                  ((impOptions.Length > 0) ? impOptions.Substring(0, 1) : ";");

                if (FdlgSeparator.ShowDialog() == DialogResult.OK)
                {
                    Hashtable requestParams = new Hashtable();

                    requestParams.Add("ALedgerNumber", FLedgerNumber);
                    requestParams.Add("Delimiter", FdlgSeparator.SelectedSeparator);
                    requestParams.Add("DateFormatString", FdlgSeparator.DateFormat);
                    requestParams.Add("DatesMayBeIntegers", datesMayBeIntegers);
                    requestParams.Add("NumberFormat", FdlgSeparator.NumberFormat);
                    requestParams.Add("NewLine", Environment.NewLine);

                    bool Repeat = true;

                    while (Repeat)
                    {
                        Repeat = false;

                        TVerificationResultCollection AMessages = new TVerificationResultCollection();
                        GiftBatchTDSAGiftDetailTable  NeedRecipientLedgerNumber = new GiftBatchTDSAGiftDetailTable();

                        Thread ImportThread = new Thread(() => ImportGiftBatches(
                                                             requestParams,
                                                             FdlgSeparator.FileContent,
                                                             out AMessages,
                                                             out ImportOK,
                                                             out RefreshGUIAfterImport,
                                                             out NeedRecipientLedgerNumber));

                        using (TProgressDialog ImportDialog = new TProgressDialog(ImportThread))
                        {
                            ImportDialog.ShowDialog();
                        }

                        // If NeedRecipientLedgerNumber contains data then AMessages will only ever contain
                        // one message alerting the user that no data has been imported.
                        // We do not want to show this as we will be displaying another more detailed message.
                        if (NeedRecipientLedgerNumber.Rows.Count == 0)
                        {
                            if (TVerificationHelper.ResultsContainErrorCode(AMessages, PetraErrorCodes.ERR_DB_SERIALIZATION_EXCEPTION))
                            {
                                TConcurrentServerTransactions.ShowTransactionSerializationExceptionDialog();
                            }
                            else
                            {
                                ShowMessages(AMessages);
                            }
                        }

                        // if the import contains gifts with Motivation Group 'GIFT' and that have a Family recipient with no Gift Destination
                        // then the import will have failed and we need to alert the user
                        if (NeedRecipientLedgerNumber.Rows.Count > 0)
                        {
                            bool OfferToRunImportAgain            = true;
                            bool DoNotShowMessageBoxEverytime     = false;
                            TFrmExtendedMessageBox.TResult Result = TFrmExtendedMessageBox.TResult.embrUndefined;
                            int count = 1;

                            // for each gift in which the recipient needs a Git Destination
                            foreach (GiftBatchTDSAGiftDetailRow Row in NeedRecipientLedgerNumber.Rows)
                            {
                                if (!DoNotShowMessageBoxEverytime)
                                {
                                    string CheckboxText = string.Empty;

                                    // only show checkbox if there is at least one more occurrence of this error
                                    if (NeedRecipientLedgerNumber.Rows.Count - count > 0)
                                    {
                                        CheckboxText = string.Format(
                                            Catalog.GetString(
                                                "Do this for all further occurrences ({0})?"), NeedRecipientLedgerNumber.Rows.Count - count);
                                    }

                                    TFrmExtendedMessageBox extendedMessageBox = new TFrmExtendedMessageBox(FPetraUtilsObject.GetForm());

                                    extendedMessageBox.ShowDialog(string.Format(
                                                                      Catalog.GetString(
                                                                          "Gift Import has been cancelled as the recipient '{0}' ({1}) has no Gift Destination assigned."),
                                                                      Row.RecipientDescription, Row.RecipientKey) +
                                                                  "\n\r\n\r\n\r" +
                                                                  Catalog.GetString("Do you want to assign a Gift Destination to this partner now?"),
                                                                  Catalog.GetString("Import Errors"),
                                                                  CheckboxText,
                                                                  TFrmExtendedMessageBox.TButtons.embbYesNo, TFrmExtendedMessageBox.TIcon.embiWarning);
                                    Result = extendedMessageBox.GetResult(out DoNotShowMessageBoxEverytime);
                                }

                                if (Result == TFrmExtendedMessageBox.TResult.embrYes)
                                {
                                    // allow the user to assign a Gift Destingation
                                    TFrmGiftDestination GiftDestinationForm = new TFrmGiftDestination(FPetraUtilsObject.GetForm(), Row.RecipientKey);
                                    GiftDestinationForm.ShowDialog();
                                }
                                else
                                {
                                    OfferToRunImportAgain = false;

                                    if (DoNotShowMessageBoxEverytime)
                                    {
                                        break;
                                    }
                                }

                                count++;
                            }

                            // if the user has clicked yes to assigning Gift Destinations then offer to restart the import
                            if (OfferToRunImportAgain &&
                                (MessageBox.Show(Catalog.GetString("Would you like to import this Gift Batch again?"),
                                                 Catalog.GetString("Gift Import"), MessageBoxButtons.YesNo, MessageBoxIcon.Question,
                                                 MessageBoxDefaultButton.Button2)
                                 == DialogResult.Yes))
                            {
                                Repeat = true;
                            }
                        }
                    }
                }

                // We save the defaults even if ok is false - because the client will probably want to try and import
                //   the same file again after correcting any errors
                SaveUserDefaults(OFileDialog);

                if (ImportOK)
                {
                    MessageBox.Show(Catalog.GetString("Your data was imported successfully!"),
                                    Catalog.GetString("Gift Import"),
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Information);
                }

                if (ImportOK)
                {
                    FMyUserControl.LoadBatchesForCurrentYear();
                    FMyForm.GetBatchControl().SelectRowInBatchGrid(1);

                    DataView allNewBatches = new DataView(AMainDS.AGiftBatch);

                    allNewBatches.RowFilter = String.Format("{0} > {1}",
                                                            AGiftBatchTable.GetBatchNumberDBName(),
                                                            CurrentTopBatchNumber);

                    foreach (DataRowView drv in allNewBatches)
                    {
                        drv.Row.SetModified();
                    }

                    FPetraUtilsObject.SetChangedFlag();
                    //Force initial inactive values check
                    FMyForm.SaveChangesManual(FMyForm.FCurrentGiftBatchAction);
                }
                else if (RefreshGUIAfterImport)
                {
                    FMyUserControl.LoadBatchesForCurrentYear();
                    FMyForm.GetBatchControl().SelectRowInBatchGrid(1);
                }
            }
            finally
            {
                FMyForm.FCurrentGiftBatchAction = Logic.TExtraGiftBatchChecks.GiftBatchAction.NONE;
            }
        }
Example #22
0
        public void SpeedTestLoadIntoTypedTable()
        {
            TDBTransaction ReadTransaction = null;
            DateTime before = DateTime.Now;
            DateTime after = DateTime.Now;
            GiftBatchTDS ds = new GiftBatchTDS();

            DBAccess.GDBAccessObj.GetNewOrExistingAutoReadTransaction(
                IsolationLevel.ReadCommitted,
                TEnforceIsolationLevel.eilMinimum,
                ref ReadTransaction,
                delegate
                {
                    string sql = "SELECT PUB_a_gift_detail.*, false AS AlreadyMatched, PUB_a_gift_batch.a_batch_status_c AS BatchStatus " +
                                 "FROM PUB_a_gift_batch, PUB_a_gift_detail " +
                                 "WHERE PUB_a_gift_detail.a_ledger_number_i = PUB_a_gift_batch.a_ledger_number_i AND PUB_a_gift_detail.a_batch_number_i = PUB_a_gift_batch.a_batch_number_i";

                    before = DateTime.Now;
                    DataTable untyped = DBAccess.GDBAccessObj.SelectDT(sql, "test", ReadTransaction);
                    after = DateTime.Now;

                    TLogging.Log(String.Format("loading all {0} gift details into an untyped table took {1} milliseconds",
                            untyped.Rows.Count,
                            (after.Subtract(before)).TotalMilliseconds));

                    GiftBatchTDSAGiftDetailTable typed = new GiftBatchTDSAGiftDetailTable();
                    before = DateTime.Now;
                    DBAccess.GDBAccessObj.SelectDT(typed, sql, ReadTransaction, new OdbcParameter[0], 0, 0);
                    after = DateTime.Now;

                    TLogging.Log(String.Format("loading all {0} gift details into a typed table took {1} milliseconds",
                            typed.Rows.Count,
                            (after.Subtract(before)).TotalMilliseconds));

                    AMotivationDetailAccess.LoadAll(ds, ReadTransaction);

                    before = DateTime.Now;
                    DBAccess.GDBAccessObj.Select(ds, sql, ds.AGiftDetail.TableName, ReadTransaction);
                    after = DateTime.Now;
                });

            TLogging.Log(String.Format("loading all {0} gift details into a typed dataset took {1} milliseconds",
                    ds.AGiftDetail.Rows.Count,
                    (after.Subtract(before)).TotalMilliseconds));

            before = DateTime.Now;
            GiftBatchTDS ds2 = new GiftBatchTDS();
            ds2.Merge(ds.AGiftDetail);
            after = DateTime.Now;

            TLogging.Log(String.Format("merging typed table into other dataset took {0} milliseconds",
                    (after.Subtract(before)).TotalMilliseconds));
        }
        // auto populate recipient info using the donor's last gift
        private void AutoPopulateGiftDetail(Int64 ADonorKey)
        {
            FAutoPopulatingGift = true;

            try
            {
                AGiftTable GiftTable = new AGiftTable();
                GiftBatchTDSAGiftDetailTable GiftDetailTable = new GiftBatchTDSAGiftDetailTable();

                // check if the donor has another gift in this same batch
                foreach (AGiftRow GiftRow in FMainDS.AGift.Rows)
                {
                    if ((GiftRow.RowState != DataRowState.Deleted) && (GiftRow.DonorKey == ADonorKey)
                        && (GiftRow.GiftTransactionNumber != GetSelectedDetailRow().GiftTransactionNumber))
                    {
                        GiftTable.Rows.Add((object[])GiftRow.ItemArray.Clone());
                    }
                }

                // if the donor does have another gift then get the AGiftDetail records for the most recent gift
                if (GiftTable.Rows.Count > 0)
                {
                    // find the most recent gift (probably the last gift in the table)
                    AGiftRow LatestGiftRow = (AGiftRow)GiftTable.Rows[GiftTable.Rows.Count - 1];

                    for (int i = GiftTable.Rows.Count - 2; i >= 0; i--)
                    {
                        if (LatestGiftRow.DateEntered < ((AGiftRow)GiftTable.Rows[i]).DateEntered)
                        {
                            LatestGiftRow = (AGiftRow)GiftTable.Rows[i];
                        }
                    }

                    foreach (AGiftDetailRow GiftDetailRow in FMainDS.AGiftDetail.Rows)
                    {
                        if ((GiftDetailRow.LedgerNumber == LatestGiftRow.LedgerNumber)
                            && (GiftDetailRow.BatchNumber == LatestGiftRow.BatchNumber)
                            && (GiftDetailRow.GiftTransactionNumber == LatestGiftRow.GiftTransactionNumber))
                        {
                            GiftDetailTable.Rows.Add((object[])GiftDetailRow.ItemArray.Clone());
                        }
                    }
                }
                else
                {
                    // if the donor does not have another gift in this gift batch then search the database for
                    // the last gift from this donor
                    GiftDetailTable = TRemote.MFinance.Gift.WebConnectors.LoadDonorLastGift(ADonorKey, FLedgerNumber);
                }

                // if this is the donor's first ever gift
                if ((GiftDetailTable == null) || (GiftDetailTable.Rows.Count == 0))
                {
                    // set FirstTimeGift field in AGift to true
                    GiftBatchTDSAGiftDetailRow CurrentDetail = GetSelectedDetailRow();
                    AGiftRow CurrentGift = (AGiftRow)FMainDS.AGift.Rows.Find(
                        new object[] { CurrentDetail.LedgerNumber, CurrentDetail.BatchNumber, CurrentDetail.GiftTransactionNumber });
                    CurrentGift.FirstTimeGift = true;

                    // add donor key to list so that new donor warning can be shown
                    if (!FNewDonorsList.Contains(ADonorKey))
                    {
                        FNewDonorsList.Add(ADonorKey);
                    }
                }

                bool SplitGift = false;

                // if the last gift was a split gift (multiple details) then ask the user if they would like this new gift to also be split
                if ((GiftDetailTable != null) && (GiftDetailTable.Rows.Count > 1))
                {
                    GiftDetailTable.DefaultView.Sort = GiftBatchTDSAGiftDetailTable.GetDetailNumberDBName() + " ASC";

                    string Message = string.Format(Catalog.GetString(
                            "The last gift from this donor was a split gift.{0}{0}Here are the details:{0}"), "\n");
                    int DetailNumber = 1;

                    foreach (DataRowView dvr in GiftDetailTable.DefaultView)
                    {
                        GiftBatchTDSAGiftDetailRow Row = (GiftBatchTDSAGiftDetailRow)dvr.Row;

                        Message += DetailNumber + ")  ";

                        if (Row.RecipientKey > 0)
                        {
                            Message +=
                                string.Format(Catalog.GetString("Recipient: {0} ({1});  Motivation Group: {2};  Motivation Detail: {3};  Amount: {4}"),
                                    Row.RecipientDescription, Row.RecipientKey, Row.MotivationGroupCode, Row.MotivationDetailCode,
                                    StringHelper.FormatUsingCurrencyCode(Row.GiftTransactionAmount, GetBatchRow().CurrencyCode) +
                                    " " + FBatchRow.CurrencyCode) +
                                "\n";
                        }

                        DetailNumber++;
                    }

                    Message += "\n" + Catalog.GetString("Do you want to create the same split gift again?");

                    SplitGift = MessageBox.Show(Message, Catalog.GetString("Create Split Gift"), MessageBoxButtons.YesNo, MessageBoxIcon.Question)
                                == DialogResult.Yes;
                }

                if ((GiftDetailTable != null) && (GiftDetailTable.Rows.Count > 0))
                {
                    int CurrentTransaction = 0;

                    while (true)
                    {
                        GiftBatchTDSAGiftDetailRow Row = (GiftBatchTDSAGiftDetailRow)GiftDetailTable.DefaultView[CurrentTransaction].Row;

                        // populate gift detail
                        txtDetailDonorKey.Text = String.Format("{0:0000000000}", ADonorKey);
                        txtDetailRecipientKey.Text = String.Format("{0:0000000000}", Row.RecipientKey);
                        cmbDetailMotivationGroupCode.SetSelectedString(Row.MotivationGroupCode);
                        cmbDetailMotivationDetailCode.SetSelectedString(Row.MotivationDetailCode);
                        chkDetailConfidentialGiftFlag.Checked = Row.ConfidentialGiftFlag;
                        chkDetailChargeFlag.Checked = Row.ChargeFlag;
                        chkDetailTaxDeductible.Checked = Row.TaxDeductible;
                        ToggleTaxDeductible(this, null);
                        cmbDetailMailingCode.SetSelectedString(Row.MailingCode, -1);

                        if (SplitGift)
                        {
                            // only populate amount if a split gift
                            txtDetailGiftTransactionAmount.NumberValueDecimal = Row.GiftTransactionAmount;
                            CurrentTransaction++;

                            // if there are more details that are part of this gift
                            if (CurrentTransaction < GiftDetailTable.Rows.Count)
                            {
                                // clear previous validation errors.
                                // otherwise we get an error if the user has changed the control immediately after changing the donor key.
                                FPetraUtilsObject.VerificationResultCollection.Clear();

                                // create a new gift detail
                                CreateANewGift(false);
                            }
                            else
                            {
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
            finally
            {
                FAutoPopulatingGift = false;
            }
        }
Example #24
0
        public static GiftBatchTDSAGiftDetailTable LoadDonorLastGift(Int64 ADonorPartnerKey, Int32 ALedgerNumber)
        {
            #region Validate Arguments

            if (ADonorPartnerKey < 0)
            {
                throw new ArgumentException(String.Format(Catalog.GetString(
                            "Function:{0} - The Donor Partnerkey cannot be a negative number!"),
                        Utilities.GetMethodName(true)));
            }

            #endregion Validate Arguments

            GiftBatchTDSAGiftDetailTable LastGiftData = new GiftBatchTDSAGiftDetailTable();

            TDBTransaction Transaction = null;

            DBAccess.GDBAccessObj.GetNewOrExistingAutoReadTransaction(IsolationLevel.ReadCommitted,
                ref Transaction,
                delegate
                {
                    // load latest gift from donor
                    string Query = "SELECT Gift.*" +
                                   " FROM a_gift AS Gift" +
                                   " WHERE Gift.a_ledger_number_i = " + ALedgerNumber +
                                   " AND Gift.p_donor_key_n = " + ADonorPartnerKey +
                                   " AND Gift.a_date_entered_d =" +
                                   "(SELECT MAX(a_gift.a_date_entered_d)" +
                                   " FROM a_gift" +
                                   " WHERE a_gift.a_ledger_number_i = " + ALedgerNumber +
                                   " AND a_gift.p_donor_key_n = " + ADonorPartnerKey + ")";

                    DataTable GiftTable = DBAccess.GDBAccessObj.SelectDT(Query, AGiftTable.GetTableDBName(), Transaction);

                    if ((GiftTable == null) || (GiftTable.Rows.Count == 0))
                    {
                        return;
                    }

                    DataRow GiftRow = GiftTable.Rows[0];

                    // load gift details for the latest gift
                    Query = "SELECT a_gift_detail.*, p_partner.p_partner_short_name_c AS RecipientDescription" +
                            " FROM a_gift_detail, p_partner" +
                            " WHERE a_gift_detail.a_ledger_number_i = " + ALedgerNumber +
                            " AND a_gift_detail.a_batch_number_i = " + GiftRow[AGiftTable.GetBatchNumberDBName()] +
                            " AND a_gift_detail.a_gift_transaction_number_i = " + GiftRow[AGiftTable.GetGiftTransactionNumberDBName()] +
                            " AND a_gift_detail.p_recipient_key_n = p_partner.p_partner_key_n";

                    DBAccess.GDBAccessObj.SelectDT(LastGiftData, Query, Transaction);
                });

            LastGiftData.AcceptChanges();

            return LastGiftData;
        }
Example #25
0
        private void ParseTransactionLine(AGiftRow AGift, AGiftBatchRow AGiftBatch, ref AGiftRow APreviousGift, int ANumberOfColumns,
            ref decimal ATotalBatchAmount, ref string AImportMessage, int ARowNumber, TVerificationResultCollection AMessages,
            TValidationControlsDict AValidationControlsDictGift, TValidationControlsDict AValidationControlsDictGiftDetail,
            ACostCentreTable AValidationCostCentreTable, AMotivationGroupTable AValidationMotivationGroupTable,
            AMotivationDetailTable AValidationMotivationDetailTable, AMethodOfGivingTable AValidationMethodOfGivingTable,
            AMethodOfPaymentTable AValidationMethodOfPaymentTable,
            ref GiftBatchTDSAGiftDetailTable ANeedRecipientLedgerNumber, out AGiftDetailRow AGiftDetails)
        {
            // Is this the format with extra columns?
            // Actually if it has the extra columns but does not have the optional final 8 columns we cannot distiguish using this test...
            //   A file without extra columns will have between 13 and 21 columns - depending on whether some of the optional ones at the end are included.
            //   A file with extra columns will be between 19 and 27.
            //  So any count between 19 and 21 is ambiguous.  We will assume that if the file has extra columns it also has
            //   at least enough of the optional ones to exceed 21.
            bool HasExtraColumns = (ANumberOfColumns > 21);

            AImportMessage = Catalog.GetString("Importing the gift data");

            AGift.DonorKey = ImportInt64(Catalog.GetString("Donor key"),
                FMainDS.AGift.ColumnDonorKey, ARowNumber, AMessages, AValidationControlsDictGift);

            ImportString(Catalog.GetString("short name of donor (unused)"), null, null); // unused

            // This group is optional and database NULL's are allowed
            AGift.MethodOfGivingCode = ImportString(Catalog.GetString("Method of giving Code"),
                FMainDS.AGift.ColumnMethodOfGivingCode, AValidationControlsDictGift, false);
            AGift.MethodOfPaymentCode = ImportString(Catalog.GetString("Method Of Payment Code"),
                FMainDS.AGift.ColumnMethodOfPaymentCode, AValidationControlsDictGift, false);
            AGift.Reference = ImportString(Catalog.GetString("Reference"),
                FMainDS.AGift.ColumnReference, AValidationControlsDictGift, false);
            AGift.ReceiptLetterCode = ImportString(Catalog.GetString("Receipt letter code"),
                FMainDS.AGift.ColumnReceiptLetterCode, AValidationControlsDictGift, false);

            if (HasExtraColumns)
            {
                ImportInt32(Catalog.GetString("Receipt number"),
                    FMainDS.AGift.ColumnReceiptNumber, ARowNumber, AMessages, AValidationControlsDictGift);
                ImportBoolean(Catalog.GetString("First time gift"),
                    FMainDS.AGift.ColumnFirstTimeGift, AValidationControlsDictGift);
                ImportBoolean(Catalog.GetString("Receipt printed"),
                    FMainDS.AGift.ColumnReceiptPrinted, AValidationControlsDictGift);
            }

            AImportMessage = Catalog.GetString("Importing the gift details");

            AGiftDetails = FMainDS.AGiftDetail.NewRowTyped(true);

            if ((APreviousGift != null) && (AGift.DonorKey == APreviousGift.DonorKey)
                && (AGift.MethodOfGivingCode == APreviousGift.MethodOfGivingCode)
                && (AGift.MethodOfPaymentCode == APreviousGift.MethodOfPaymentCode)
                && (AGift.Reference == APreviousGift.Reference)
                && (AGift.ReceiptLetterCode == APreviousGift.ReceiptLetterCode)
                && (AGift.ReceiptNumber == APreviousGift.ReceiptNumber)
                && (AGift.FirstTimeGift == APreviousGift.FirstTimeGift)
                && (AGift.ReceiptPrinted == APreviousGift.ReceiptPrinted))
            {
                // this row is a new detail for the previousGift
                AGift = APreviousGift;
                AGift.LastDetailNumber++;
                AGiftDetails.DetailNumber = AGift.LastDetailNumber;
            }
            else
            {
                APreviousGift = AGift;
                AGift.LedgerNumber = AGiftBatch.LedgerNumber;
                AGift.BatchNumber = AGiftBatch.BatchNumber;
                AGift.GiftTransactionNumber = AGiftBatch.LastGiftNumber + 1;
                AGiftBatch.LastGiftNumber++;
                AGift.LastDetailNumber = 1;
                FMainDS.AGift.Rows.Add(AGift);
                AGiftDetails.DetailNumber = 1;
            }

            AGiftDetails.LedgerNumber = AGift.LedgerNumber;
            AGiftDetails.BatchNumber = AGiftBatch.BatchNumber;
            AGiftDetails.GiftTransactionNumber = AGift.GiftTransactionNumber;
            FMainDS.AGiftDetail.Rows.Add(AGiftDetails);

            AGiftDetails.RecipientKey = ImportInt64(Catalog.GetString("Recipient key"),
                FMainDS.AGiftDetail.ColumnRecipientKey, ARowNumber, AMessages, AValidationControlsDictGiftDetail);

            ImportString(Catalog.GetString("short name of recipient (unused)"), null, null); // unused

            if (HasExtraColumns)
            {
                ImportInt32(Catalog.GetString("Recipient ledger number"),
                    FMainDS.AGiftDetail.ColumnRecipientLedgerNumber, ARowNumber, AMessages, AValidationControlsDictGiftDetail);
            }

            // we always calculate RecipientLedgerNumber
            AGiftDetails.RecipientLedgerNumber = TGiftTransactionWebConnector.GetRecipientFundNumber(
                AGiftDetails.RecipientKey, AGiftBatch.GlEffectiveDate);

            decimal currentGiftAmount = ImportDecimal(Catalog.GetString("Gift amount"),
                FMainDS.AGiftDetail.ColumnGiftTransactionAmount, ARowNumber, AMessages, AValidationControlsDictGiftDetail);
            AGiftDetails.GiftTransactionAmount = currentGiftAmount;     // amount in batch currency
            ATotalBatchAmount += currentGiftAmount;

            AGiftDetails.GiftAmount = GLRoutines.Divide(currentGiftAmount, AGiftBatch.ExchangeRateToBase);      // amount in ledger currency

            if (HasExtraColumns)
            {
                // amount in international currency
                ImportDecimal(Catalog.GetString("Gift amount intl"),
                    FMainDS.AGiftDetail.ColumnGiftAmountIntl, ARowNumber, AMessages, AValidationControlsDictGiftDetail);
            }

            AGiftDetails.ConfidentialGiftFlag = ImportBoolean(Catalog.GetString("Confidential gift"),
                FMainDS.AGiftDetail.ColumnConfidentialGiftFlag, AValidationControlsDictGiftDetail, "no");
            AGiftDetails.MotivationGroupCode = ImportString(Catalog.GetString("Motivation group code"),
                FMainDS.AGiftDetail.ColumnMotivationGroupCode, AValidationControlsDictGiftDetail);
            AGiftDetails.MotivationDetailCode = ImportString(Catalog.GetString("Motivation detail"),
                FMainDS.AGiftDetail.ColumnMotivationDetailCode, AValidationControlsDictGiftDetail);

            if (HasExtraColumns)
            {
                ImportString(Catalog.GetString("Cost centre code"),
                    FMainDS.AGiftDetail.ColumnCostCentreCode, AValidationControlsDictGiftDetail);
            }

            // "In Petra Cost Centre is always inferred from recipient field and motivation detail so is not needed in the import."
            AGiftDetails.CostCentreCode = InferCostCentre(AGiftDetails);

            // All the remaining columns are optional and can contain database NULL
            AGiftDetails.GiftCommentOne = ImportString(Catalog.GetString("Gift comment one"),
                FMainDS.AGiftDetail.ColumnGiftCommentOne, AValidationControlsDictGiftDetail, false);
            string commentOneType = ImportString(Catalog.GetString("Comment one type"),
                FMainDS.AGiftDetail.ColumnCommentOneType, AValidationControlsDictGiftDetail, false);

            AGiftDetails.MailingCode = ImportString(Catalog.GetString("Mailing code"),
                FMainDS.AGiftDetail.ColumnMailingCode, AValidationControlsDictGiftDetail, false);

            AGiftDetails.GiftCommentTwo = ImportString(Catalog.GetString("Gift comment two"),
                FMainDS.AGiftDetail.ColumnGiftCommentTwo, AValidationControlsDictGiftDetail, false);
            string commentTwoType = ImportString(Catalog.GetString("Comment two type"),
                FMainDS.AGiftDetail.ColumnCommentTwoType, AValidationControlsDictGiftDetail, false);
            AGiftDetails.GiftCommentThree = ImportString(Catalog.GetString("Gift comment three"),
                FMainDS.AGiftDetail.ColumnGiftCommentThree, AValidationControlsDictGiftDetail, false);
            string commentThreeType = ImportString(Catalog.GetString("Comment three type"),
                FMainDS.AGiftDetail.ColumnCommentThreeType, AValidationControlsDictGiftDetail, false);

            SetCommentTypeCase(ref commentOneType);
            AGiftDetails.CommentOneType = commentOneType;

            SetCommentTypeCase(ref commentTwoType);
            AGiftDetails.CommentOneType = commentTwoType;

            SetCommentTypeCase(ref commentThreeType);
            AGiftDetails.CommentOneType = commentThreeType;

            // Find the default Tax deductabilty from the motivation detail. This ensures that the column can be missing.
            AMotivationDetailRow motivationDetailRow = (AMotivationDetailRow)AValidationMotivationDetailTable.Rows.Find(
                new object[] { FLedgerNumber, AGiftDetails.MotivationGroupCode, AGiftDetails.MotivationDetailCode });
            string defaultTaxDeductible =
                ((motivationDetailRow != null) && !motivationDetailRow.IsTaxDeductibleAccountNull()
                 && motivationDetailRow.TaxDeductible) ? "yes" : "no";

            AGiftDetails.TaxDeductible = ImportBoolean(Catalog.GetString("Tax deductible"),
                FMainDS.AGiftDetail.ColumnTaxDeductible, AValidationControlsDictGiftDetail, defaultTaxDeductible);

            // Date entered cannot be imported although it can be modified in the GUI.
            // This is because it would have to be the last column in the import for compatibility
            // but it belongs with the gift and not the detail so it would need to go in an earlier column.
            // For now the import date entered is the effective date.
            AGift.DateEntered = AGiftBatch.GlEffectiveDate;

            // Enforce the correct case for our GIFT constant
            if (String.Compare(AGiftDetails.MotivationGroupCode, MFinanceConstants.MOTIVATION_GROUP_GIFT, true) == 0)
            {
                AGiftDetails.MotivationGroupCode = MFinanceConstants.MOTIVATION_GROUP_GIFT;
            }

            TPartnerClass RecipientClass;
            string RecipientDescription;
            TPartnerServerLookups.GetPartnerShortName(AGiftDetails.RecipientKey, out RecipientDescription, out RecipientClass);

            // If the gift has a Family recipient with no Gift Destination then the import will fail. Gift is added to a table and returned to client.
            if ((AGiftDetails.RecipientLedgerNumber == 0) && (AGiftDetails.MotivationGroupCode == MFinanceConstants.MOTIVATION_GROUP_GIFT))
            {
                if (RecipientClass == TPartnerClass.FAMILY)
                {
                    ((GiftBatchTDSAGiftDetailRow)AGiftDetails).RecipientDescription = RecipientDescription;
                    ANeedRecipientLedgerNumber.Rows.Add((object[])AGiftDetails.ItemArray.Clone());
                }
            }

            AImportMessage = Catalog.GetString("Validating the gift data");

            int messageCountBeforeValidate = AMessages.Count;

            // Do our standard validation on this gift
            AGiftValidation.Validate(this, AGift, ref AMessages, AValidationControlsDictGift);
            TSharedFinanceValidation_Gift.ValidateGiftManual(this, AGift, AGiftBatch.BatchYear, AGiftBatch.BatchPeriod,
                null, ref AMessages, AValidationControlsDictGift, AValidationMethodOfGivingTable, AValidationMethodOfPaymentTable);

            AImportMessage = Catalog.GetString("Validating the gift details data");

            AGiftDetailValidation.Validate(this, AGiftDetails, ref AMessages, AValidationControlsDictGiftDetail);
            TSharedFinanceValidation_Gift.ValidateGiftDetailManual(this, (GiftBatchTDSAGiftDetailRow)AGiftDetails,
                ref AMessages, AValidationControlsDictGiftDetail, RecipientClass, AValidationCostCentreTable, AValidationMotivationGroupTable,
                AValidationMotivationDetailTable, AGiftDetails.RecipientKey);

            for (int i = messageCountBeforeValidate; i < AMessages.Count; i++)
            {
                ((TVerificationResult)AMessages[i]).OverrideResultContext(String.Format(MCommonConstants.StrValidationErrorInLine, ARowNumber));

                if (AMessages[i] is TScreenVerificationResult)
                {
                    TVerificationResult downgrade = new TVerificationResult((TScreenVerificationResult)AMessages[i]);
                    AMessages.RemoveAt(i);
                    AMessages.Insert(i, downgrade);
                }
            }
        }
        /// <summary>
        /// Main method to post a specified batch
        /// </summary>
        /// <param name="ACurrentBatchRow">The batch row to post</param>
        /// <returns>True if the batch was successfully posted</returns>
        public bool PostBatch(AGiftBatchRow ACurrentBatchRow)
        {
            if ((ACurrentBatchRow == null) || (ACurrentBatchRow.BatchStatus != MFinanceConstants.BATCH_UNPOSTED))
            {
                return false;
            }

            FSelectedBatchNumber = ACurrentBatchRow.BatchNumber;
            TVerificationResultCollection Verifications;

            try
            {
                FMyForm.Cursor = Cursors.WaitCursor;

                FMyForm.EnsureGiftDataPresent(FLedgerNumber, FSelectedBatchNumber);

                GiftBatchTDSAGiftDetailTable BatchGiftDetails = new GiftBatchTDSAGiftDetailTable();

                foreach (GiftBatchTDSAGiftDetailRow Row in FMainDS.AGiftDetail.Rows)
                {
                    if (Row.BatchNumber == FSelectedBatchNumber)
                    {
                        BatchGiftDetails.Rows.Add((object[])Row.ItemArray.Clone());
                    }
                }

                // there are no gifts in this batch!
                if (BatchGiftDetails.Rows.Count == 0)
                {
                    FMyForm.Cursor = Cursors.Default;
                    MessageBox.Show(Catalog.GetString("Batch is empty!"), Catalog.GetString("Posting failed"),
                        MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    return false;
                }

                bool CancelledDueToExWorkerOrAnonDonor;

                // save first, then post
                if (!FMyForm.SaveChangesForPosting(BatchGiftDetails, out CancelledDueToExWorkerOrAnonDonor))
                {
                    FMyForm.Cursor = Cursors.Default;

                    if (!CancelledDueToExWorkerOrAnonDonor)
                    {
                        // saving failed, therefore do not try to post
                        MessageBox.Show(Catalog.GetString("The batch was not posted due to problems during saving; ") + Environment.NewLine +
                            Catalog.GetString("Please first save the batch, and then post it!"));
                    }

                    return false;
                }
            }
            finally
            {
                FMyForm.Cursor = Cursors.Default;
            }

            //Check for missing international exchange rate
            bool IsTransactionInIntlCurrency = false;

            if (FMyForm.InternationalCurrencyExchangeRate(ACurrentBatchRow, out IsTransactionInIntlCurrency, true) == 0)
            {
                return false;
            }

            //Check for inactive KeyMinistries
            DataTable GiftsWithInactiveKeyMinistries;

            if (TRemote.MFinance.Gift.WebConnectors.InactiveKeyMinistriesFoundInBatch(FLedgerNumber, FSelectedBatchNumber,
                    out GiftsWithInactiveKeyMinistries))
            {
                string listOfRow = "Gift   Detail   Recipient        KeyMinistry" + Environment.NewLine;
                listOfRow += "------------------------------------------------";

                foreach (DataRow dr in GiftsWithInactiveKeyMinistries.Rows)
                {
                    listOfRow += String.Format("{0}{1:0000}    {2:00}    {3:00000000000}    {4}",
                        Environment.NewLine,
                        dr[0],
                        dr[1],
                        dr[2],
                        dr[3]);
                }

                string msg = String.Format(Catalog.GetString("Cannot post Batch {0} as inactive Key Ministries found in gifts:{1}{1}{2}"),
                    FSelectedBatchNumber,
                    Environment.NewLine,
                    listOfRow);

                MessageBox.Show(msg, Catalog.GetString("Inactive Key Ministries Found"));

                return false;
            }

            // ask if the user really wants to post the batch
            if (MessageBox.Show(String.Format(Catalog.GetString("Do you really want to post gift batch {0}?"),
                        FSelectedBatchNumber),
                    Catalog.GetString("Confirm posting of Gift Batch"),
                    MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
            {
                return false;
            }

            Verifications = new TVerificationResultCollection();

            try
            {
                FPostingInProgress = true;

                Thread postingThread = new Thread(() => PostGiftBatch(out Verifications));

                using (TProgressDialog dialog = new TProgressDialog(postingThread))
                {
                    dialog.ShowDialog();
                }

                if (!TVerificationHelper.IsNullOrOnlyNonCritical(Verifications))
                {
                    string ErrorMessages = String.Empty;

                    foreach (TVerificationResult verif in Verifications)
                    {
                        ErrorMessages += "[" + verif.ResultContext + "] " +
                                         verif.ResultTextCaption + ": " +
                                         verif.ResultText + Environment.NewLine;
                    }

                    System.Windows.Forms.MessageBox.Show(ErrorMessages, Catalog.GetString("Posting failed"));
                }
                else
                {
                    MessageBox.Show(Catalog.GetString("The batch has been posted successfully!"));

                    return true;
                }
            }
            catch
            {
                //Do nothing
            }
            finally
            {
                FPostingInProgress = false;
            }

            return false;
        }
Example #27
0
        /// <summary>
        /// Import Gift batch data
        /// The data file contents from the client is sent as a string, imported in the database
        /// and committed immediately
        /// </summary>
        /// <param name="ARequestParams">Hashtable containing the given params </param>
        /// <param name="AImportString">Big parts of the export file as a simple String</param>
        /// <param name="ANeedRecipientLedgerNumber">Gifts in this table are responsible for failing the
        /// import becuase their Family recipients do not have an active Gift Destination</param>
        /// <param name="AMessages">Additional messages to display in a messagebox</param>
        /// <returns>false if error</returns>
        public bool ImportGiftBatches(
            Hashtable ARequestParams,
            String AImportString,
            out GiftBatchTDSAGiftDetailTable ANeedRecipientLedgerNumber,
            out TVerificationResultCollection AMessages
            )
        {
            TProgressTracker.InitProgressTracker(DomainManager.GClientID.ToString(),
                Catalog.GetString("Importing Gift Batches"),
                100);

            TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                Catalog.GetString("Initialising"),
                0);

            AMessages = new TVerificationResultCollection();
            FMainDS = new GiftBatchTDS();
            StringReader sr = new StringReader(AImportString);
            ANeedRecipientLedgerNumber = new GiftBatchTDSAGiftDetailTable();

            // Parse the supplied parameters
            FDelimiter = (String)ARequestParams["Delimiter"];
            FLedgerNumber = (Int32)ARequestParams["ALedgerNumber"];
            FDateFormatString = (String)ARequestParams["DateFormatString"];
            String NumberFormat = (String)ARequestParams["NumberFormat"];
            FNewLine = (String)ARequestParams["NewLine"];

            // Set culture from parameters
            FCultureInfoNumberFormat = new CultureInfo(NumberFormat.Equals("American") ? "en-US" : "de-DE");
            FCultureInfoDate = new CultureInfo("en-GB");
            FCultureInfoDate.DateTimeFormat.ShortDatePattern = FDateFormatString;

            bool TaxDeductiblePercentageEnabled = Convert.ToBoolean(
                TSystemDefaults.GetSystemDefault(SharedConstants.SYSDEFAULT_TAXDEDUCTIBLEPERCENTAGE, "FALSE"));

            // Initialise our working variables
            TDBTransaction Transaction = null;
            AGiftBatchRow giftBatch = null;
            decimal totalBatchAmount = 0;
            Int32 RowNumber = 0;
            Int32 InitialTextLength = AImportString.Length;
            Int32 TextProcessedLength = 0;
            Int32 PercentDone = 10;
            Int32 PreviousPercentDone = 0;
            bool ok = false;

            string ImportMessage = Catalog.GetString("Initialising");

            // Create some validation dictionaries
            TValidationControlsDict ValidationControlsDictBatch = new TValidationControlsDict();
            TValidationControlsDict ValidationControlsDictGift = new TValidationControlsDict();
            TValidationControlsDict ValidationControlsDictGiftDetail = new TValidationControlsDict();

            try
            {
                // This needs to be initialised because we will be calling the method
                TSharedFinanceValidationHelper.GetValidPeriodDatesDelegate = @TAccountingPeriodsWebConnector.GetPeriodDates;
                TSharedFinanceValidationHelper.GetFirstDayOfAccountingPeriodDelegate = @TAccountingPeriodsWebConnector.GetFirstDayOfAccountingPeriod;

                // Get a new transaction
                Transaction = DBAccess.GDBAccessObj.BeginTransaction(IsolationLevel.Serializable);

                // If we did not succeed there is something wrong (a transaction is already dangling somewhere?)
                if (Transaction == null)
                {
                    throw new Exception(Catalog.GetString(
                            "Could not create a new import transaction because an existing transaction has not completed."));
                }

                // Load supplementary tables that we are going to need for validation
                ALedgerTable LedgerTable = ALedgerAccess.LoadByPrimaryKey(FLedgerNumber, Transaction);
                AAccountTable AccountTable = AAccountAccess.LoadViaALedger(FLedgerNumber, Transaction);
                ACostCentreTable CostCentreTable = ACostCentreAccess.LoadViaALedger(FLedgerNumber, Transaction);
                AMotivationGroupTable MotivationGroupTable = AMotivationGroupAccess.LoadViaALedger(FLedgerNumber, Transaction);
                AMotivationDetailTable MotivationDetailTable = AMotivationDetailAccess.LoadViaALedger(FLedgerNumber, Transaction);
                AAccountPropertyTable AccountPropertyTable = AAccountPropertyAccess.LoadViaALedger(FLedgerNumber, Transaction);
                AAccountingPeriodTable AccountingPeriodTable = AAccountingPeriodAccess.LoadViaALedger(FLedgerNumber, Transaction);
                AMethodOfGivingTable MethodOfGivingTable = AMethodOfGivingAccess.LoadAll(Transaction);
                AMethodOfPaymentTable MethodOfPaymentTable = AMethodOfPaymentAccess.LoadAll(Transaction);
                ACurrencyTable CurrencyTable = ACurrencyAccess.LoadAll(Transaction);

                if (LedgerTable.Rows.Count == 0)
                {
                    throw new Exception(String.Format(Catalog.GetString("Ledger {0} doesn't exist."), FLedgerNumber));
                }

                FLedgerBaseCurrency = ((ALedgerRow)LedgerTable.Rows[0]).BaseCurrency;
                FLedgerIntlCurrency = ((ALedgerRow)LedgerTable.Rows[0]).IntlCurrency;

                ACorporateExchangeRateTable CorporateExchangeToLedgerTable = ACorporateExchangeRateAccess.LoadViaACurrencyFromCurrencyCode(
                    FLedgerBaseCurrency,
                    Transaction);
                ADailyExchangeRateTable DailyExchangeToLedgerTable = ADailyExchangeRateAccess.LoadViaACurrencyToCurrencyCode(FLedgerBaseCurrency,
                    Transaction);
                ADailyExchangeRateTable DailyExchangeToIntlTable = ADailyExchangeRateAccess.LoadViaACurrencyToCurrencyCode(FLedgerIntlCurrency,
                    Transaction);

                ImportMessage = Catalog.GetString("Parsing first line");
                AGiftRow previousGift = null;

                // Go round a loop reading the file line by line
                FImportLine = sr.ReadLine();

                while (FImportLine != null)
                {
                    RowNumber++;

                    TextProcessedLength += (FImportLine.Length + FNewLine.Length);
                    PercentDone = 10 + ((TextProcessedLength * 90) / InitialTextLength);

                    // skip empty lines and commented lines
                    if ((FImportLine.Trim().Length > 0) && !FImportLine.StartsWith("/*") && !FImportLine.StartsWith("#"))
                    {
                        int numberOfElements = StringHelper.GetCSVList(FImportLine, FDelimiter).Count;

                        // Read the row analysisType - there is no 'validation' on this so we can make the call with null parameters
                        string RowType = ImportString(Catalog.GetString("row type"), null, null);

                        if (RowType == "B")
                        {
                            ImportMessage = Catalog.GetString("Parsing a batch row");

                            // It is a Batch row
                            if (numberOfElements < 8)
                            {
                                AMessages.Add(new TVerificationResult(String.Format(MCommonConstants.StrParsingErrorInLine, RowNumber),
                                        Catalog.GetString(
                                            "Wrong number of batch columns.  The correct number is either 8 columns (in which case the gift type is assumed to be 'Gift') or 9 columns, which allows for alternative gift types."),
                                        TResultSeverity.Resv_Critical));

                                FImportLine = sr.ReadLine();

                                if (FImportLine != null)
                                {
                                    TextProcessedLength += (FImportLine.Length + FNewLine.Length);
                                }

                                continue;
                            }

                            //Check if this is the start of a new batch (i.e. not the first batch)
                            if ((previousGift != null) && (giftBatch != null))
                            {
                                //New batch so set total amount of Batch for previous batch
                                giftBatch.BatchTotal = totalBatchAmount;

                                if (TVerificationHelper.IsNullOrOnlyNonCritical(AMessages))
                                {
                                    ImportMessage = Catalog.GetString("Saving batch");
                                    AGiftBatchAccess.SubmitChanges(FMainDS.AGiftBatch, Transaction);
                                    FMainDS.AGiftBatch.AcceptChanges();

                                    ImportMessage = Catalog.GetString("Saving gift");
                                    AGiftAccess.SubmitChanges(FMainDS.AGift, Transaction);
                                    FMainDS.AGift.AcceptChanges();

                                    ImportMessage = Catalog.GetString("Saving giftdetails");
                                    AGiftDetailAccess.SubmitChanges(FMainDS.AGiftDetail, Transaction);
                                    FMainDS.AGiftDetail.AcceptChanges();
                                }

                                previousGift = null;
                            }

                            ImportMessage = Catalog.GetString("Starting new batch");
                            totalBatchAmount = 0;

                            // Parse the complete line and validate it
                            ParseBatchLine(ref giftBatch, ref Transaction, ref LedgerTable, ref ImportMessage, RowNumber, AMessages,
                                ValidationControlsDictBatch, AccountTable, AccountPropertyTable, AccountingPeriodTable, CostCentreTable,
                                CorporateExchangeToLedgerTable, CurrencyTable);

                            if (TVerificationHelper.IsNullOrOnlyNonCritical(AMessages))
                            {
                                // This row passes validation so we can do final actions if the batch is not in the ledger currency
                                if (giftBatch.CurrencyCode != FLedgerBaseCurrency)
                                {
                                    ImportMessage = Catalog.GetString("Updating foreign exchange data");

                                    // Validation will have ensured that we have a corporate rate for the effective date
                                    // We need to know what that rate is...
                                    DateTime firstOfMonth = new DateTime(giftBatch.GlEffectiveDate.Year, giftBatch.GlEffectiveDate.Month, 1);
                                    ACorporateExchangeRateRow corporateRateRow = (ACorporateExchangeRateRow)CorporateExchangeToLedgerTable.Rows.Find(
                                        new object[] { giftBatch.CurrencyCode, FLedgerBaseCurrency, firstOfMonth });
                                    decimal corporateRate = corporateRateRow.RateOfExchange;

                                    if (Math.Abs((giftBatch.ExchangeRateToBase - corporateRate) / corporateRate) > 0.20m)
                                    {
                                        AMessages.Add(new TVerificationResult(String.Format(MCommonConstants.StrImportValidationWarningInLine,
                                                    RowNumber),
                                                String.Format(Catalog.GetString(
                                                        "The exchange rate of {0} differs from the Corporate Rate of {1} for the month commencing {2} by more than 20 percent."),
                                                    giftBatch.ExchangeRateToBase, corporateRate, StringHelper.DateToLocalizedString(firstOfMonth)),
                                                TResultSeverity.Resv_Noncritical));
                                    }

                                    // we need to create a daily exchange rate pair for the transaction date
                                    // start with To Ledger currency
                                    if (UpdateDailyExchangeRateTable(DailyExchangeToLedgerTable, giftBatch.CurrencyCode, FLedgerBaseCurrency,
                                            giftBatch.ExchangeRateToBase, giftBatch.GlEffectiveDate))
                                    {
                                        ADailyExchangeRateAccess.SubmitChanges(DailyExchangeToLedgerTable, Transaction);
                                        DailyExchangeToLedgerTable.AcceptChanges();

                                        AMessages.Add(new TVerificationResult(String.Format(MCommonConstants.StrImportInformationForLine, RowNumber),
                                                String.Format(Catalog.GetString("Added exchange rate of {0} to Daily Exchange Rate table for {1}"),
                                                    giftBatch.ExchangeRateToBase, StringHelper.DateToLocalizedString(giftBatch.GlEffectiveDate)),
                                                TResultSeverity.Resv_Info));
                                    }

                                    // Now the inverse for From Ledger currency
                                    ADailyExchangeRateTable DailyExchangeFromTable =
                                        ADailyExchangeRateAccess.LoadViaACurrencyFromCurrencyCode(giftBatch.CurrencyCode, Transaction);
                                    decimal inverseRate = Math.Round(1 / giftBatch.ExchangeRateToBase, 10);

                                    if (UpdateDailyExchangeRateTable(DailyExchangeFromTable, FLedgerBaseCurrency, giftBatch.CurrencyCode,
                                            inverseRate, giftBatch.GlEffectiveDate))
                                    {
                                        ADailyExchangeRateAccess.SubmitChanges(DailyExchangeFromTable, Transaction);
                                    }
                                }
                            }
                        }
                        else if (RowType == "T")
                        {
                            ImportMessage = Catalog.GetString("Parsing a transaction row");

                            // It is a Transaction row
                            if (numberOfElements < 13) // Perhaps this CSV file is a summary, and can't be imported?
                            {
                                AMessages.Add(new TVerificationResult(String.Format(MCommonConstants.StrParsingErrorInLine, RowNumber),
                                        Catalog.GetString("Wrong number of gift columns. Expected at least 13 columns. (This may be a summary?)"),
                                        TResultSeverity.Resv_Critical));
                                FImportLine = sr.ReadLine();

                                if (FImportLine != null)
                                {
                                    TextProcessedLength += (FImportLine.Length + FNewLine.Length);
                                }

                                continue;
                            }

                            if (giftBatch == null)
                            {
                                AMessages.Add(new TVerificationResult(String.Format(MCommonConstants.StrParsingErrorInLine, RowNumber),
                                        Catalog.GetString(
                                            "Expected a GiftBatch line, but found a Gift Transaction. Will create a dummy working batch for the current period."),
                                        TResultSeverity.Resv_Critical));

                                // in order to carry on we will make a dummy batch and force the date to fit
                                giftBatch = TGiftBatchFunctions.CreateANewGiftBatchRow(ref FMainDS,
                                    ref Transaction,
                                    ref LedgerTable,
                                    FLedgerNumber,
                                    DateTime.Today);
                            }

                            // Parse the line into a new row
                            AGiftRow gift = FMainDS.AGift.NewRowTyped(true);
                            AGiftDetailRow giftDetails;
                            ParseTransactionLine(gift,
                                giftBatch,
                                ref previousGift,
                                numberOfElements,
                                ref totalBatchAmount,
                                ref ImportMessage,
                                RowNumber,
                                AMessages,
                                ValidationControlsDictGift,
                                ValidationControlsDictGiftDetail,
                                CostCentreTable,
                                MotivationGroupTable,
                                MotivationDetailTable,
                                MethodOfGivingTable,
                                MethodOfPaymentTable,
                                ref ANeedRecipientLedgerNumber,
                                out giftDetails);

                            if (TaxDeductiblePercentageEnabled)
                            {
                                // Sets TaxDeductiblePct and uses it to calculate the tax deductibility amounts for a Gift Detail
                                TGift.SetDefaultTaxDeductibilityData(ref giftDetails, gift.DateEntered, Transaction);
                            }

                            if (TVerificationHelper.IsNullOrOnlyNonCritical(AMessages))
                            {
                                if ((FLedgerBaseCurrency != FLedgerIntlCurrency) && (giftDetails.GiftAmountIntl != 0))
                                {
                                    ImportMessage = Catalog.GetString("Updating international exchange rate data");

                                    // We should add a Daily Exchange Rate row pair
                                    // start with To Ledger currency
                                    decimal fromIntlToBase = GLRoutines.Divide(giftDetails.GiftAmount, giftDetails.GiftAmountIntl);

                                    if (UpdateDailyExchangeRateTable(DailyExchangeToLedgerTable, FLedgerIntlCurrency, FLedgerBaseCurrency,
                                            fromIntlToBase, giftBatch.GlEffectiveDate))
                                    {
                                        ADailyExchangeRateAccess.SubmitChanges(DailyExchangeToLedgerTable, Transaction);
                                        DailyExchangeToLedgerTable.AcceptChanges();

                                        AMessages.Add(new TVerificationResult(String.Format(MCommonConstants.StrImportInformationForLine, RowNumber),
                                                String.Format(Catalog.GetString(
                                                        "Added exchange rate of {0} to Daily Exchange Rate table for ledger currency / international currency on {1}"),
                                                    fromIntlToBase, StringHelper.DateToLocalizedString(giftBatch.GlEffectiveDate)),
                                                TResultSeverity.Resv_Info));
                                    }

                                    // Now the inverse for From Ledger currency
                                    decimal inverseRate = GLRoutines.Divide(giftDetails.GiftAmountIntl, giftDetails.GiftAmount);

                                    if (UpdateDailyExchangeRateTable(DailyExchangeToIntlTable, FLedgerBaseCurrency, FLedgerIntlCurrency,
                                            inverseRate, giftBatch.GlEffectiveDate))
                                    {
                                        ADailyExchangeRateAccess.SubmitChanges(DailyExchangeToIntlTable, Transaction);
                                        DailyExchangeToIntlTable.AcceptChanges();
                                    }
                                }
                            }
                        } // If known row analysisType
                        else
                        {
                            AMessages.Add(new TVerificationResult(String.Format(MCommonConstants.StrParsingErrorInLine, RowNumber),
                                    Catalog.GetString("Invalid Row Type. Perhaps using wrong CSV separator?"), TResultSeverity.Resv_Critical));
                        }
                    }  // if the CSV line qualifies

                    if (AMessages.Count > 100)
                    {
                        // This probably means that it is a big file and the user has made the same mistake many times over
                        break;
                    }

                    // Update progress tracker every few percent
                    if ((PercentDone - PreviousPercentDone) > 3)
                    {
                        TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                            String.Format(Catalog.GetString("Importing row {0}"), RowNumber),
                            (PercentDone > 98) ? 98 : PercentDone);
                        PreviousPercentDone = PercentDone;
                    }

                    // Read the next line
                    FImportLine = sr.ReadLine();

                    if (FImportLine != null)
                    {
                        TextProcessedLength += (FImportLine.Length + FNewLine.Length);
                    }
                }  // while CSV lines

                // Finished reading the file - did we have critical errors?
                if (!TVerificationHelper.IsNullOrOnlyNonCritical(AMessages))
                {
                    TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                        Catalog.GetString("Batch has critical errors"),
                        0);

                    // Record error count
                    AMessages.Add(new TVerificationResult(MCommonConstants.StrImportInformation,
                            String.Format(Catalog.GetString("{0} messages reported."), AMessages.Count), TResultSeverity.Resv_Info));

                    if (FImportLine == null)
                    {
                        // We did reach the end of the file
                        AMessages.Add(new TVerificationResult(MCommonConstants.StrImportInformation,
                                Catalog.GetString(
                                    "Reached the end of file but errors occurred. When these errors are fixed the batch will import successfully."),
                                TResultSeverity.Resv_Info));
                    }
                    else
                    {
                        // We gave up before the end
                        AMessages.Add(new TVerificationResult(MCommonConstants.StrImportInformation,
                                Catalog.GetString(
                                    "Stopped reading the file after generating more than 100 messages.  The file may contian more errors beyond the ones listed here."),
                                TResultSeverity.Resv_Info));
                    }

                    TLogging.Log("Return from here!");

                    // we do not want to think about Gift Destination problems if the import has failed for another reason
                    ANeedRecipientLedgerNumber.Clear();

                    // Do the 'finally' actions and return false
                    return false;
                }

                // if the import contains gifts with Motivation Group 'GIFT' and that have a Family recipient with no Gift Destination then the import will fail
                if (ANeedRecipientLedgerNumber.Rows.Count > 0)
                {
                    return false;
                }

                // Everything is ok, so we can do our finish actions

                //Update batch total for the last batch entered.
                if (giftBatch != null)
                {
                    giftBatch.BatchTotal = totalBatchAmount;
                }

                ImportMessage = Catalog.GetString("Saving all data into the database");

                //Finally save pending changes (the last number is updated !)
                ImportMessage = Catalog.GetString("Saving final batch");
                AGiftBatchAccess.SubmitChanges(FMainDS.AGiftBatch, Transaction);
                FMainDS.AGiftBatch.AcceptChanges();

                ImportMessage = Catalog.GetString("Saving final gift");
                AGiftAccess.SubmitChanges(FMainDS.AGift, Transaction);
                FMainDS.AGift.AcceptChanges();

                ImportMessage = Catalog.GetString("Saving final giftdetails");
                AGiftDetailAccess.SubmitChanges(FMainDS.AGiftDetail, Transaction);
                FMainDS.AGiftDetail.AcceptChanges();

                ImportMessage = Catalog.GetString("Saving ledger changes");
                ALedgerAccess.SubmitChanges(LedgerTable, Transaction);
                FMainDS.ALedger.AcceptChanges();

                // Commit the transaction (we know that we got a new one and can control it)
                DBAccess.GDBAccessObj.CommitTransaction();
                ok = true;
            }
            catch (Exception ex)
            {
                // Parse the exception text for possible references to database foreign keys
                // Make the message more friendly in that case
                string friendlyExceptionText = MakeFriendlyFKExceptions(ex);

                if (AMessages == null)
                {
                    AMessages = new TVerificationResultCollection();
                }

                if (RowNumber > 0)
                {
                    // At least we made a start
                    string msg = ImportMessage;

                    if (friendlyExceptionText.Length > 0)
                    {
                        msg += FNewLine + friendlyExceptionText;
                    }

                    if (ImportMessage.StartsWith(Catalog.GetString("Saving ")))
                    {
                        // Do not display any specific line number because these errors occur outside the parsing loop
                        AMessages.Add(new TVerificationResult(String.Format(MCommonConstants.StrExceptionWhileSavingBatch, giftBatch.BatchDescription),
                                msg, TResultSeverity.Resv_Critical));
                    }
                    else
                    {
                        AMessages.Add(new TVerificationResult(String.Format(MCommonConstants.StrExceptionWhileParsingLine, RowNumber),
                                msg, TResultSeverity.Resv_Critical));
                    }
                }
                else
                {
                    // We got an exception before we even started parsing the rows (getting a transaction?)
                    AMessages.Add(new TVerificationResult(String.Format(MCommonConstants.StrExceptionWhileParsingLine, RowNumber),
                            friendlyExceptionText, TResultSeverity.Resv_Critical));
                }

                TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                    Catalog.GetString("Exception Occurred"),
                    0);

                ok = false;
            }
            finally
            {
                try
                {
                    sr.Close();
                }
                catch (Exception Exc)
                {
                    TLogging.Log("An Exception occured while closing the Import File:" + Environment.NewLine + Exc.ToString());

                    if (AMessages == null)
                    {
                        AMessages = new TVerificationResultCollection();
                    }

                    AMessages.Add(new TVerificationResult(Catalog.GetString("Import exception"),
                            Catalog.GetString("A problem was encountered while closing the Import File:"),
                            TResultSeverity.Resv_Critical));

                    TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                        Catalog.GetString("Exception Occurred"),
                        0);

                    TProgressTracker.FinishJob(DomainManager.GClientID.ToString());

                    throw;
                }

                if (ok)
                {
                    TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                        Catalog.GetString("Gift batch import successful"),
                        100);
                }
                else
                {
                    DBAccess.GDBAccessObj.RollbackTransaction();

                    if (AMessages == null)
                    {
                        AMessages = new TVerificationResultCollection();
                    }

                    AMessages.Add(new TVerificationResult(MCommonConstants.StrImportInformation,
                            Catalog.GetString("None of the data from the import was saved."),
                            TResultSeverity.Resv_Critical));

                    TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                        Catalog.GetString("Data could not be saved."),
                        0);
                }

                TProgressTracker.FinishJob(DomainManager.GClientID.ToString());
            } // end of 'finally'

            return ok;
        }
Example #28
0
        private void FPetraUtilsObject_DataSavingStarted_NewDonorWarning()
        {
            GetDataFromControls();

            FGiftDetailTable = FMainDS.AGiftDetail.GetChangesTyped();
        }
Example #29
0
        /// <summary>
        /// Import Gift Transactions from a file
        /// </summary>
        /// <param name="ARequestParams"></param>
        /// <param name="AImportString"></param>
        /// <param name="AGiftBatchNumber"></param>
        /// <param name="ANeedRecipientLedgerNumber"></param>
        /// <param name="AMessages"></param>
        /// <returns></returns>
        public bool ImportGiftTransactions(
            Hashtable ARequestParams,
            String AImportString,
            Int32 AGiftBatchNumber,
            out GiftBatchTDSAGiftDetailTable ANeedRecipientLedgerNumber,
            out TVerificationResultCollection AMessages
            )
        {
            TProgressTracker.InitProgressTracker(DomainManager.GClientID.ToString(),
                Catalog.GetString("Importing Gift Batches"),
                100);

            TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                Catalog.GetString("Initialising"),
                5);

            AMessages = new TVerificationResultCollection();
            FMainDS = new GiftBatchTDS();
            StringReader sr = new StringReader(AImportString);
            ANeedRecipientLedgerNumber = new GiftBatchTDSAGiftDetailTable();


            // Parse the supplied parameters
            FDelimiter = (String)ARequestParams["Delimiter"];
            FLedgerNumber = (Int32)ARequestParams["ALedgerNumber"];
            FDateFormatString = (String)ARequestParams["DateFormatString"];
            String NumberFormat = (String)ARequestParams["NumberFormat"];
            FNewLine = (String)ARequestParams["NewLine"];

            // Set culture from parameters
            FCultureInfoNumberFormat = new CultureInfo(NumberFormat.Equals("American") ? "en-US" : "de-DE");
            FCultureInfoDate = new CultureInfo("en-GB");
            FCultureInfoDate.DateTimeFormat.ShortDatePattern = FDateFormatString;

            bool TaxDeductiblePercentageEnabled = Convert.ToBoolean(
                TSystemDefaults.GetSystemDefault(SharedConstants.SYSDEFAULT_TAXDEDUCTIBLEPERCENTAGE, "FALSE"));

            // Initialise our working variables
            TDBTransaction Transaction = null;
            decimal totalBatchAmount = 0;
            Int32 RowNumber = 0;
            Int32 InitialTextLength = AImportString.Length;
            Int32 TextProcessedLength = 0;
            Int32 PercentDone = 10;
            Int32 PreviousPercentDone = 0;
            bool ok = false;

            string ImportMessage = Catalog.GetString("Initialising");

            // Create some validation dictionaries
            TValidationControlsDict ValidationControlsDictGift = new TValidationControlsDict();
            TValidationControlsDict ValidationControlsDictGiftDetail = new TValidationControlsDict();

            try
            {
                // This needs to be initialised because we will be calling the method
                TSharedFinanceValidationHelper.GetValidPeriodDatesDelegate = @TAccountingPeriodsWebConnector.GetPeriodDates;
                TSharedFinanceValidationHelper.GetFirstDayOfAccountingPeriodDelegate = @TAccountingPeriodsWebConnector.GetFirstDayOfAccountingPeriod;

                // Get a new transaction
                Transaction = DBAccess.GDBAccessObj.BeginTransaction(IsolationLevel.Serializable);

                // If we did not succeed there is something wrong (a transaction is already dangling somewhere?)
                if (Transaction == null)
                {
                    throw new Exception(Catalog.GetString(
                            "Could not create a new import transaction because an existing transaction has not completed."));
                }

                // Load supplementary tables that we are going to need for validation
                ALedgerTable LedgerTable = ALedgerAccess.LoadByPrimaryKey(FLedgerNumber, Transaction);
                ACostCentreTable CostCentreTable = ACostCentreAccess.LoadViaALedger(FLedgerNumber, Transaction);
                AMotivationGroupTable MotivationGroupTable = AMotivationGroupAccess.LoadViaALedger(FLedgerNumber, Transaction);
                AMotivationDetailTable MotivationDetailTable = AMotivationDetailAccess.LoadViaALedger(FLedgerNumber, Transaction);
                AMethodOfGivingTable MethodOfGivingTable = AMethodOfGivingAccess.LoadAll(Transaction);
                AMethodOfPaymentTable MethodOfPaymentTable = AMethodOfPaymentAccess.LoadAll(Transaction);

                AGiftBatchTable giftBatchTable = AGiftBatchAccess.LoadViaALedger(FLedgerNumber, Transaction);
                DataView giftBatchDV = new DataView(giftBatchTable, String.Format("{0}={1}",
                        AGiftBatchTable.GetBatchNumberDBName(), AGiftBatchNumber), "", DataViewRowState.CurrentRows);
                FMainDS.AGiftBatch.ImportRow(giftBatchDV[0].Row);
                FMainDS.AcceptChanges();
                AGiftBatchRow giftBatch = (AGiftBatchRow)FMainDS.AGiftBatch.Rows.Find(new object[] { FLedgerNumber, AGiftBatchNumber });

                if (LedgerTable.Rows.Count == 0)
                {
                    throw new Exception(String.Format(Catalog.GetString("Ledger {0} doesn't exist."), FLedgerNumber));
                }

                ImportMessage = Catalog.GetString("Parsing first line");
                AGiftRow previousGift = null;

                // Go round a loop reading the file line by line
                FImportLine = sr.ReadLine();

                while (FImportLine != null)
                {
                    RowNumber++;

                    TextProcessedLength += (FImportLine.Length + FNewLine.Length);
                    PercentDone = 10 + ((TextProcessedLength * 90) / InitialTextLength);

                    // skip empty lines and commented lines
                    if ((FImportLine.Trim().Length > 0) && !FImportLine.StartsWith("/*") && !FImportLine.StartsWith("#"))
                    {
                        // number of elements is incremented by 1 as though the line started with 'T'
                        int numberOfElements = StringHelper.GetCSVList(FImportLine, FDelimiter).Count + 1;

                        // It is a Transaction row
                        if (numberOfElements < 13) // Perhaps this CSV file is a summary, and can't be imported?
                        {
                            AMessages.Add(new TVerificationResult(String.Format(MCommonConstants.StrParsingErrorInLine, RowNumber),
                                    Catalog.GetString("Wrong number of gift columns. Expected at least 13 columns. (This may be a summary?)"),
                                    TResultSeverity.Resv_Critical));
                            FImportLine = sr.ReadLine();

                            if (FImportLine != null)
                            {
                                TextProcessedLength += (FImportLine.Length + FNewLine.Length);
                            }

                            continue;
                        }

                        // Parse the line into a new row
                        ImportMessage = Catalog.GetString("Parsing transaction line");
                        AGiftRow gift = FMainDS.AGift.NewRowTyped(true);
                        AGiftDetailRow giftDetails;
                        ParseTransactionLine(gift,
                            giftBatch,
                            ref previousGift,
                            numberOfElements,
                            ref totalBatchAmount,
                            ref ImportMessage,
                            RowNumber,
                            AMessages,
                            ValidationControlsDictGift,
                            ValidationControlsDictGiftDetail,
                            CostCentreTable,
                            MotivationGroupTable,
                            MotivationDetailTable,
                            MethodOfGivingTable,
                            MethodOfPaymentTable,
                            ref ANeedRecipientLedgerNumber,
                            out giftDetails);

                        if (TaxDeductiblePercentageEnabled)
                        {
                            // Sets TaxDeductiblePct and uses it to calculate the tax deductibility amounts for a Gift Detail
                            TGift.SetDefaultTaxDeductibilityData(ref giftDetails, gift.DateEntered, Transaction);
                        }
                    }

                    if (AMessages.Count > 100)
                    {
                        // This probably means that it is a big file and the user has made the same mistake many times over
                        break;
                    }

                    // Update progress tracker every few percent
                    if ((PercentDone - PreviousPercentDone) > 3)
                    {
                        TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                            String.Format(Catalog.GetString("Importing row {0}"), RowNumber),
                            (PercentDone > 98) ? 98 : PercentDone);
                        PreviousPercentDone = PercentDone;
                    }

                    // Read the next line
                    FImportLine = sr.ReadLine();

                    if (FImportLine != null)
                    {
                        TextProcessedLength += (FImportLine.Length + FNewLine.Length);
                    }
                } // while CSV lines

                // Finished reading the file - did we have critical errors?
                if (!TVerificationHelper.IsNullOrOnlyNonCritical(AMessages))
                {
                    TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                        Catalog.GetString("Batch has critical errors"),
                        100);

                    // Record error count
                    AMessages.Add(new TVerificationResult(MCommonConstants.StrImportInformation,
                            String.Format(Catalog.GetString("{0} messages reported."), AMessages.Count), TResultSeverity.Resv_Info));

                    if (FImportLine == null)
                    {
                        // We did reach the end of the file
                        AMessages.Add(new TVerificationResult(MCommonConstants.StrImportInformation,
                                Catalog.GetString(
                                    "Reached the end of file but errors occurred. When these errors are fixed the batch will import successfully."),
                                TResultSeverity.Resv_Info));
                    }
                    else
                    {
                        // We gave up before the end
                        AMessages.Add(new TVerificationResult(MCommonConstants.StrImportInformation,
                                Catalog.GetString(
                                    "Stopped reading the file after generating more than 100 messages.  The file may contian more errors beyond the ones listed here."),
                                TResultSeverity.Resv_Info));
                    }

                    TLogging.Log("Return from here!");

                    // we do not want to think about Gift Destination problems if the import has failed for another reason
                    ANeedRecipientLedgerNumber.Clear();

                    // Do the 'finally' actions and return false
                    return false;
                }

                // if the import contains gifts with Motivation Group 'GIFT' and that have a Family recipient with no Gift Destination then the import will fail
                if (ANeedRecipientLedgerNumber.Rows.Count > 0)
                {
                    // Do the 'finally' actions and return false
                    return false;
                }

                // Everything is ok, so we can do our finish actions

                //Update batch total for the last batch entered.
                if (giftBatch != null)
                {
                    giftBatch.BatchTotal = totalBatchAmount;
                }

                TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                    Catalog.GetString("Saving all data into the database"),
                    100);

                //Finally save pending changes (the last number is updated !)
                ImportMessage = Catalog.GetString("Saving gift batch");
                AGiftBatchAccess.SubmitChanges(FMainDS.AGiftBatch, Transaction);
                FMainDS.AGiftBatch.AcceptChanges();

                ImportMessage = Catalog.GetString("Saving gifts");
                AGiftAccess.SubmitChanges(FMainDS.AGift, Transaction);
                FMainDS.AGift.AcceptChanges();

                ImportMessage = Catalog.GetString("Saving giftdetails");
                AGiftDetailAccess.SubmitChanges(FMainDS.AGiftDetail, Transaction);
                FMainDS.AGiftDetail.AcceptChanges();

                ImportMessage = Catalog.GetString("Saving ledger");
                ALedgerAccess.SubmitChanges(LedgerTable, Transaction);
                LedgerTable.AcceptChanges();

                // Commit the transaction (we know that we got a new one and can control it)
                DBAccess.GDBAccessObj.CommitTransaction();
                ok = true;
            }
            catch (Exception ex)
            {
                // Parse the exception text for possible references to database foreign keys
                // Make the message more friendly in that case
                string friendlyExceptionText = MakeFriendlyFKExceptions(ex);

                if (AMessages == null)
                {
                    AMessages = new TVerificationResultCollection();
                }

                if (RowNumber > 0)
                {
                    // At least we made a start
                    string msg = ImportMessage;

                    if (friendlyExceptionText.Length > 0)
                    {
                        msg += FNewLine + friendlyExceptionText;
                    }

                    if (ImportMessage.StartsWith(Catalog.GetString("Saving ")))
                    {
                        // Do not display any specific line number because these errors occur outside the parsing loop
                        AMessages.Add(new TVerificationResult(MCommonConstants.StrExceptionWhileSavingTransactions,
                                msg, TResultSeverity.Resv_Critical));
                    }
                    else
                    {
                        AMessages.Add(new TVerificationResult(String.Format(MCommonConstants.StrExceptionWhileParsingLine, RowNumber),
                                msg, TResultSeverity.Resv_Critical));
                    }
                }
                else
                {
                    // We got an exception before we even started parsing the rows (getting a transaction?)
                    AMessages.Add(new TVerificationResult(String.Format(MCommonConstants.StrExceptionWhileParsingLine, RowNumber),
                            friendlyExceptionText, TResultSeverity.Resv_Critical));
                }

                TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                    Catalog.GetString("Exception Occurred"),
                    0);

                ok = false;
            }
            finally
            {
                try
                {
                    sr.Close();
                }
                catch (Exception Exc)
                {
                    TLogging.Log("An Exception occured while closing the Import File:" + Environment.NewLine + Exc.ToString());

                    if (AMessages == null)
                    {
                        AMessages = new TVerificationResultCollection();
                    }

                    AMessages.Add(new TVerificationResult(Catalog.GetString("Import exception"),
                            Catalog.GetString("A problem was encountered while closing the Import File:"),
                            TResultSeverity.Resv_Critical));

                    TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                        Catalog.GetString("Exception Occurred"),
                        0);

                    TProgressTracker.FinishJob(DomainManager.GClientID.ToString());

                    throw;
                }

                if (ok)
                {
                    TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                        Catalog.GetString("Gift batch import successful"),
                        100);
                }
                else
                {
                    DBAccess.GDBAccessObj.RollbackTransaction();

                    if (AMessages == null)
                    {
                        AMessages = new TVerificationResultCollection();
                    }

                    AMessages.Add(new TVerificationResult(MCommonConstants.StrImportInformation,
                            Catalog.GetString("None of the data from the import was saved."),
                            TResultSeverity.Resv_Critical));

                    TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                        Catalog.GetString("Data could not be saved."),
                        0);
                }

                TProgressTracker.FinishJob(DomainManager.GClientID.ToString());
            } // end of 'finally'

            return ok;
        }
Example #30
0
        /// <summary>
        /// Import a transactions file or a clipboard equivalent
        /// </summary>
        /// <param name="ACurrentBatchRow">The batch to import to</param>
        /// <param name="AImportSource">The import source - eg File or Clipboard</param>
        /// <returns>True if the import was successful</returns>
        public bool ImportTransactions(AGiftBatchRow ACurrentBatchRow, TGiftImportDataSourceEnum AImportSource)
        {
            bool           ok = false;
            String         importString;
            String         impOptions;
            OpenFileDialog dialog      = null;
            Boolean        IsPlainText = false;

            if (FPetraUtilsObject.HasChanges)
            {
                // saving failed, therefore do not try to import
                MessageBox.Show(Catalog.GetString("Please save before calling this function!"), Catalog.GetString(
                                    "Gift Import"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(false);
            }

            if ((ACurrentBatchRow == null) || (ACurrentBatchRow.BatchStatus != MFinanceConstants.BATCH_UNPOSTED))
            {
                MessageBox.Show(Catalog.GetString("Please select an unposted batch to import transactions."), Catalog.GetString(
                                    "Gift Import"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(false);
            }

            if (ACurrentBatchRow.LastGiftNumber > 0)
            {
                if (MessageBox.Show(Catalog.GetString(
                                        "The current batch already contains some gift transactions.  Do you really want to add more transactions to this batch?"),
                                    Catalog.GetString("Gift Transaction Import"),
                                    MessageBoxButtons.YesNo,
                                    MessageBoxIcon.Question,
                                    MessageBoxDefaultButton.Button2) == DialogResult.No)
                {
                    return(false);
                }
            }

            FdlgSeparator = new TDlgSelectCSVSeparator(false);

            if (AImportSource == TGiftImportDataSourceEnum.FromClipboard)
            {
                importString = Clipboard.GetText(TextDataFormat.UnicodeText);

                if ((importString == null) || (importString.Length == 0))
                {
                    MessageBox.Show(Catalog.GetString("Please first copy data from your spreadsheet application!"),
                                    Catalog.GetString("Failure"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return(false);
                }

                impOptions = TUserDefaults.GetStringDefault("Imp Options", ";American");
                String dateFormatString = TUserDefaults.GetStringDefault("Imp Date", "MDY");
                FdlgSeparator = new TDlgSelectCSVSeparator(false);
                FdlgSeparator.SelectedSeparator = "\t";
                FdlgSeparator.CSVData           = importString;
                FdlgSeparator.DateFormat        = dateFormatString;

                if (impOptions.Length > 1)
                {
                    FdlgSeparator.NumberFormat = impOptions.Substring(1);
                }
            }
            else if (AImportSource == TGiftImportDataSourceEnum.FromFile)
            {
                dialog = new OpenFileDialog();

                string exportPath = TClientSettings.GetExportPath();
                string fullPath   = TUserDefaults.GetStringDefault("Imp Filename",
                                                                   exportPath + Path.DirectorySeparatorChar + "import.csv");
                TImportExportDialogs.SetOpenFileDialogFilePathAndName(dialog, fullPath, exportPath);

                dialog.Title  = Catalog.GetString("Import Transactions from CSV File");
                dialog.Filter = Catalog.GetString("Gift Transactions files (*.csv)|*.csv|Text Files (*.txt)|*.txt");
                impOptions    = TUserDefaults.GetStringDefault("Imp Options", ";" + TDlgSelectCSVSeparator.NUMBERFORMAT_AMERICAN);

                // This call fixes Windows7 Open File Dialogs.  It must be the line before ShowDialog()
                TWin7FileOpenSaveDialog.PrepareDialog(Path.GetFileName(fullPath));

                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    Boolean fileCanOpen = FdlgSeparator.OpenCsvFile(dialog.FileName);

                    if (!fileCanOpen)
                    {
                        MessageBox.Show(Catalog.GetString("Unable to open file."),
                                        Catalog.GetString("Gift Import"),
                                        MessageBoxButtons.OK,
                                        MessageBoxIcon.Stop);
                        return(false);
                    }

                    importString = File.ReadAllText(dialog.FileName, Encoding.Default);
                    IsPlainText  = (Path.GetExtension(dialog.FileName).ToLower() == ".txt");

                    String dateFormatString = TUserDefaults.GetStringDefault("Imp Date", "MDY");
                    FdlgSeparator.DateFormat = dateFormatString;

                    if (impOptions.Length > 1)
                    {
                        FdlgSeparator.NumberFormat = impOptions.Substring(1);
                    }

                    FdlgSeparator.SelectedSeparator = impOptions.Substring(0, 1);
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                // unknown source!!  The following need a value...
                impOptions   = String.Empty;
                importString = String.Empty;
            }

            if (IsPlainText || (FdlgSeparator.ShowDialog() == DialogResult.OK))
            {
                Hashtable requestParams = new Hashtable();

                requestParams.Add("ALedgerNumber", FLedgerNumber);
                requestParams.Add("Delimiter", FdlgSeparator.SelectedSeparator);
                requestParams.Add("DateFormatString", FdlgSeparator.DateFormat);
                requestParams.Add("NumberFormat", FdlgSeparator.NumberFormat);
                requestParams.Add("NewLine", Environment.NewLine);

                bool Repeat = true;

                while (Repeat)
                {
                    Repeat = false;

                    TVerificationResultCollection AMessages = new TVerificationResultCollection();
                    GiftBatchTDSAGiftDetailTable  NeedRecipientLedgerNumber = new GiftBatchTDSAGiftDetailTable();

                    Thread ImportThread = new Thread(() => ImportGiftTransactions(
                                                         requestParams,
                                                         importString,
                                                         ACurrentBatchRow.BatchNumber,
                                                         out AMessages,
                                                         out ok,
                                                         out NeedRecipientLedgerNumber));

                    using (TProgressDialog ImportDialog = new TProgressDialog(ImportThread))
                    {
                        ImportDialog.ShowDialog();
                    }

                    ShowMessages(AMessages);

                    // if the import contains gifts with Motivation Group 'GIFT' and that have a Family recipient with no Gift Destination
                    // then the import will have failed and we need to alert the user
                    if (NeedRecipientLedgerNumber.Rows.Count > 0)
                    {
                        bool OfferToRunImportAgain = true;

                        // for each gift in which the recipient needs a Git Destination
                        foreach (GiftBatchTDSAGiftDetailRow Row in NeedRecipientLedgerNumber.Rows)
                        {
                            if (MessageBox.Show(string.Format(
                                                    Catalog.GetString(
                                                        "Gift Import has been cancelled as the recipient '{0}' ({1}) has no Gift Destination assigned."),
                                                    Row.RecipientDescription, Row.RecipientKey) +
                                                "\n\n" +
                                                Catalog.GetString("Do you want to assign a Gift Destination to this partner now?"),
                                                Catalog.GetString("Gift Import"), MessageBoxButtons.YesNo, MessageBoxIcon.Warning)
                                == DialogResult.Yes)
                            {
                                // allow the user to assign a Gift Destingation
                                TFrmGiftDestination GiftDestinationForm = new TFrmGiftDestination(FPetraUtilsObject.GetForm(), Row.RecipientKey);
                                GiftDestinationForm.ShowDialog();
                            }
                            else
                            {
                                OfferToRunImportAgain = false;
                            }
                        }

                        // if the user has clicked yes to assigning Gift Destinations then offer to restart the import
                        if (OfferToRunImportAgain &&
                            (MessageBox.Show(Catalog.GetString("Would you like to import these Gift Transactions again?"),
                                             Catalog.GetString("Gift Import"), MessageBoxButtons.YesNo, MessageBoxIcon.Question,
                                             MessageBoxDefaultButton.Button1)
                             == DialogResult.Yes))
                        {
                            Repeat = true;
                        }
                    }
                }

                // We save the defaults even if ok is false - because the client will probably want to try and import
                //   the same file again after correcting any errors
                SaveUserDefaults(dialog, impOptions);
            }

            if (ok)
            {
                MessageBox.Show(Catalog.GetString("Your data was imported successfully!"),
                                Catalog.GetString("Gift Import"),
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);

                //FMyUserControl.LoadBatchesForCurrentYear();
                FPetraUtilsObject.DisableSaveButton();
            }

            return(ok);
        }
        /// <summary>
        /// auto populate new gift recipient info using the donor's last gift
        /// </summary>
        /// <param name="ADonorKey"></param>
        /// <param name="APartnerShortName"></param>
        /// <param name="AGiftTransactionNumber"></param>
        private void AutoPopulateGiftDetail(Int64 ADonorKey, String APartnerShortName, Int32 AGiftTransactionNumber)
        {
            FAutoPopulatingGiftInProcess = true;

            bool IsSplitGift = false;

            DateTime LatestUnpostedGiftDateEntered = new DateTime(1900, 1, 1);

            try
            {
                //Check for Donor in loaded gift batches
                // and record most recent date entered
                AGiftTable DonorRecentGiftsTable             = new AGiftTable();
                GiftBatchTDSAGiftDetailTable GiftDetailTable = new GiftBatchTDSAGiftDetailTable();

                AGiftRow MostRecentLoadedGiftForDonorRow = null;

                DataView giftDV = new DataView(FMainDS.AGift);

                giftDV.RowStateFilter = DataViewRowState.CurrentRows;

                giftDV.RowFilter = string.Format("{0}={1} And Not ({2}={3} And {4}={5})",
                                                 AGiftTable.GetDonorKeyDBName(),
                                                 ADonorKey,
                                                 AGiftTable.GetBatchNumberDBName(),
                                                 FBatchNumber,
                                                 AGiftTable.GetGiftTransactionNumberDBName(),
                                                 AGiftTransactionNumber);

                giftDV.Sort = String.Format("{0} DESC, {1} DESC",
                                            AGiftTable.GetDateEnteredDBName(),
                                            AGiftTable.GetGiftTransactionNumberDBName());

                if (giftDV.Count > 0)
                {
                    //Take first row = most recent date entered value
                    MostRecentLoadedGiftForDonorRow = (AGiftRow)giftDV[0].Row;
                    LatestUnpostedGiftDateEntered   = MostRecentLoadedGiftForDonorRow.DateEntered;
                    DonorRecentGiftsTable.Rows.Add((object[])MostRecentLoadedGiftForDonorRow.ItemArray.Clone());
                }

                //Check for even more recent saved gifts on server (i.e. not necessarily loaded)
                GiftDetailTable = TRemote.MFinance.Gift.WebConnectors.LoadDonorLastPostedGift(ADonorKey, FLedgerNumber, LatestUnpostedGiftDateEntered);

                if (((GiftDetailTable != null) && (GiftDetailTable.Count > 0)))
                {
                    //UnLoaded/Saved gift from donor is more recent
                    IsSplitGift = (GiftDetailTable.Count > 1);
                }
                else if (MostRecentLoadedGiftForDonorRow != null)
                {
                    //Loaded/unsaved gift from donor is more recent
                    DataView giftDetailDV = new DataView(FMainDS.AGiftDetail);

                    giftDetailDV.RowStateFilter = DataViewRowState.CurrentRows;

                    giftDetailDV.RowFilter = string.Format("{0}={1} And {2}={3}",
                                                           AGiftDetailTable.GetBatchNumberDBName(),
                                                           MostRecentLoadedGiftForDonorRow.BatchNumber,
                                                           AGiftDetailTable.GetGiftTransactionNumberDBName(),
                                                           MostRecentLoadedGiftForDonorRow.GiftTransactionNumber);

                    foreach (DataRowView drv in giftDetailDV)
                    {
                        GiftBatchTDSAGiftDetailRow gDR = (GiftBatchTDSAGiftDetailRow)drv.Row;
                        GiftDetailTable.Rows.Add((object[])gDR.ItemArray.Clone());
                    }

                    IsSplitGift = (GiftDetailTable.Count > 1);
                }
                else
                {
                    //nothing to autocopy
                    return;
                }

                // if the last gift was a split gift (multiple details) then ask the user if they would like this new gift to also be split
                if (IsSplitGift)
                {
                    GiftDetailTable.DefaultView.Sort = GiftBatchTDSAGiftDetailTable.GetDetailNumberDBName() + " ASC";

                    string Message = string.Format(Catalog.GetString(
                                                       "The last gift from this donor was a split gift.{0}{0}Here are the details:{0}"), "\n");
                    int DetailNumber = 1;

                    foreach (DataRowView dvr in GiftDetailTable.DefaultView)
                    {
                        GiftBatchTDSAGiftDetailRow Row = (GiftBatchTDSAGiftDetailRow)dvr.Row;

                        Message += DetailNumber + ")  ";

                        if (Row.RecipientKey > 0)
                        {
                            Message +=
                                string.Format(Catalog.GetString("Recipient: {0} ({1});  Motivation Group: {2};  Motivation Detail: {3};  Amount: {4}"),
                                              Row.RecipientDescription, Row.RecipientKey, Row.MotivationGroupCode, Row.MotivationDetailCode,
                                              StringHelper.FormatUsingCurrencyCode(Row.GiftTransactionAmount, GetBatchRow().CurrencyCode) +
                                              " " + FBatchRow.CurrencyCode) +
                                "\n";
                        }

                        DetailNumber++;
                    }

                    Message += "\n" + Catalog.GetString("Do you want to create the same split gift again?");

                    if (!(MessageBox.Show(Message, Catalog.GetString(
                                              "Create Split Gift"), MessageBoxButtons.YesNo, MessageBoxIcon.Question)
                          == DialogResult.Yes))
                    {
                        if (cmbDetailMethodOfGivingCode.CanFocus)
                        {
                            cmbDetailMethodOfGivingCode.Focus();
                        }
                        else if (txtDetailReference.CanFocus)
                        {
                            txtDetailReference.Focus();
                        }

                        return;
                    }
                }

                this.Cursor = Cursors.WaitCursor;

                GiftBatchTDSAGiftDetailRow giftDetailRow = (GiftBatchTDSAGiftDetailRow)GiftDetailTable.DefaultView[0].Row;

                // Handle first row, which is FPreviouslySelectedDetailRow
                txtDetailDonorKey.Text     = String.Format("{0:0000000000}", ADonorKey);
                txtDetailRecipientKey.Text = String.Format("{0:0000000000}", giftDetailRow.RecipientKey);
                cmbDetailMotivationGroupCode.SetSelectedString(giftDetailRow.MotivationGroupCode);
                txtDetailMotivationDetailCode.Text = giftDetailRow.MotivationDetailCode;
                cmbMotivationDetailCode.SetSelectedString(giftDetailRow.MotivationDetailCode);
                chkDetailConfidentialGiftFlag.Checked = giftDetailRow.ConfidentialGiftFlag;
                // Change #5481
                chkDetailChargeFlag.Checked = true;
                cmbDetailMethodOfPaymentCode.SetSelectedString(FBatchMethodOfPayment, -1);
                cmbDetailMethodOfGivingCode.SetSelectedString(giftDetailRow.MethodOfGivingCode, -1);

                //Handle mailing code
                if (FSETAutoCopyIncludeMailingCodeFlag)
                {
                    cmbDetailMailingCode.SetSelectedString(giftDetailRow.MailingCode, -1);
                }
                else
                {
                    cmbDetailMailingCode.SelectedIndex = -1;
                }

                //Copy the comments and comment types if required
                if (FSETAutoCopyIncludeCommentsFlag)
                {
                    txtDetailGiftCommentOne.Text = giftDetailRow.GiftCommentOne;
                    cmbDetailCommentOneType.SetSelectedString(giftDetailRow.CommentOneType);
                    txtDetailGiftCommentTwo.Text = giftDetailRow.GiftCommentTwo;
                    cmbDetailCommentTwoType.SetSelectedString(giftDetailRow.CommentTwoType);
                    txtDetailGiftCommentThree.Text = giftDetailRow.GiftCommentThree;
                    cmbDetailCommentThreeType.SetSelectedString(giftDetailRow.CommentThreeType);
                }

                //Handle tax fields on current row
                if (FSETUseTaxDeductiblePercentageFlag)
                {
                    bool taxDeductible = (giftDetailRow.IsTaxDeductibleNull() ? true : giftDetailRow.TaxDeductible);
                    giftDetailRow.TaxDeductible = taxDeductible;

                    try
                    {
                        FPetraUtilsObject.SuppressChangeDetection = true;
                        chkDetailTaxDeductible.Checked            = taxDeductible;
                        EnableTaxDeductibilityPct(taxDeductible);
                    }
                    finally
                    {
                        FPetraUtilsObject.SuppressChangeDetection = false;
                    }

                    if (!IsSplitGift)
                    {
                        //Most commonly not a split gift (?)
                        if (!taxDeductible)
                        {
                            txtDeductiblePercentage.NumberValueDecimal = 0.0m;
                        }

                        txtTaxDeductAmount.NumberValueDecimal = 0.0m;
                        txtNonDeductAmount.NumberValueDecimal = 0.0m;
                    }
                    else
                    {
                        if (taxDeductible)
                        {
                            //In case the tax percentage has changed or null values in amount fields
                            ReconcileTaxDeductibleAmounts(giftDetailRow);
                        }
                        else
                        {
                            //Changing this will update the unbound amount textboxes
                            txtDeductiblePercentage.NumberValueDecimal = 0.0m;
                        }
                    }
                }

                //Process values that are not bound to a control
                giftDetailRow.ReceiptPrinted = false;
                giftDetailRow.ReceiptNumber  = 0;

                //Now process other gift details if they exist
                if (IsSplitGift)
                {
                    //Only copy amount to first row if copying split gifts
                    txtDetailGiftTransactionAmount.NumberValueDecimal = giftDetailRow.GiftTransactionAmount;

                    // clear previous validation errors.
                    // otherwise we get an error if the user has changed the control immediately after changing the donor key.
                    FPetraUtilsObject.VerificationResultCollection.Clear();

                    bool SelectEndRow = (FBatchRow.LastGiftNumber == FPreviouslySelectedDetailRow.GiftTransactionNumber);

                    //Just retain other details to add
                    giftDetailRow.Delete();
                    GiftDetailTable.AcceptChanges();

                    foreach (DataRowView drv in GiftDetailTable.DefaultView)
                    {
                        GiftBatchTDSAGiftDetailRow detailRow = (GiftBatchTDSAGiftDetailRow)drv.Row;

                        //______________________
                        //Update basic field values
                        detailRow.LedgerNumber          = FLedgerNumber;
                        detailRow.BatchNumber           = FBatchNumber;
                        detailRow.GiftTransactionNumber = AGiftTransactionNumber;
                        detailRow.DetailNumber          = ++FGift.LastDetailNumber;
                        detailRow.DonorName             = APartnerShortName;
                        detailRow.DonorClass            = FPreviouslySelectedDetailRow.DonorClass;
                        detailRow.DateEntered           = FGift.DateEntered;
                        detailRow.MethodOfPaymentCode   = FPreviouslySelectedDetailRow.MethodOfPaymentCode;
                        detailRow.ReceiptPrinted        = false;
                        detailRow.ReceiptNumber         = 0;
                        // Change #5481
                        detailRow.ChargeFlag = true;

                        if (!FSETAutoCopyIncludeMailingCodeFlag)
                        {
                            detailRow.MailingCode = string.Empty;
                        }

                        //______________________
                        //process recipient details to get most recent data
                        Int64         partnerKey       = detailRow.RecipientKey;
                        string        partnerShortName = string.Empty;
                        TPartnerClass partnerClass;
                        bool          recipientIsValid = true;

                        if (TServerLookup.TMPartner.GetPartnerShortName(partnerKey, out partnerShortName, out partnerClass))
                        {
                            detailRow.RecipientDescription = partnerShortName;
                            detailRow.RecipientClass       = partnerClass.ToString();

                            if (partnerClass == TPartnerClass.FAMILY)
                            {
                                detailRow.RecipientLedgerNumber = TRemote.MFinance.Gift.WebConnectors.GetRecipientFundNumber(partnerKey,
                                                                                                                             FGift.DateEntered);
                                detailRow.RecipientField       = detailRow.RecipientLedgerNumber;
                                detailRow.RecipientKeyMinistry = string.Empty;
                            }
                            else
                            {
                                //Class - UNIT
                                Int64  field;
                                string keyMinName;

                                recipientIsValid = TFinanceControls.GetRecipientKeyMinData(partnerKey, out field, out keyMinName);

                                detailRow.RecipientLedgerNumber = field;
                                detailRow.RecipientField        = field;
                                detailRow.RecipientKeyMinistry  = keyMinName;

                                if (!recipientIsValid)
                                {
                                    string msg =
                                        String.Format(Catalog.GetString(
                                                          "Gift: {0}, Detail: {1} has a recipient: '{2}-{3}' that is an inactive Key Ministry!"),
                                                      AGiftTransactionNumber,
                                                      detailRow.DetailNumber,
                                                      partnerKey,
                                                      keyMinName);
                                    MessageBox.Show(msg, Catalog.GetString(
                                                        "Copying Previous Split Gift"), MessageBoxButtons.OK, MessageBoxIcon.Warning);
                                }
                            }
                        }
                        else
                        {
                            recipientIsValid = false;
                            string msg = String.Format(Catalog.GetString("Gift: {0}, Detail: {1} has an invalid Recipient key: '{2}'!"),
                                                       AGiftTransactionNumber,
                                                       detailRow.DetailNumber,
                                                       partnerKey);
                            MessageBox.Show(msg, Catalog.GetString("Copying Previous Split Gift"), MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        }

                        //______________________
                        //Process motivation
                        if (string.IsNullOrEmpty(detailRow.MotivationGroupCode))
                        {
                            detailRow.MotivationGroupCode = string.Empty;
                            string msg = String.Format(Catalog.GetString("Gift: {0}, Detail: {1} has no Motivation Group!"),
                                                       AGiftTransactionNumber,
                                                       detailRow.DetailNumber);
                            MessageBox.Show(msg, Catalog.GetString("Copying Previous Split Gift"), MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        }
                        else if (string.IsNullOrEmpty(detailRow.MotivationDetailCode))
                        {
                            detailRow.MotivationDetailCode = string.Empty;
                            string msg = String.Format(Catalog.GetString("Gift: {0}, Detail: {1} has no Motivation Detail!"),
                                                       AGiftTransactionNumber,
                                                       detailRow.DetailNumber);
                            MessageBox.Show(msg, Catalog.GetString("Copying Previous Split Gift"), MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        }
                        else
                        {
                            AMotivationDetailRow motivationDetailRow = null;
                            string motivationGroup  = detailRow.MotivationGroupCode;
                            string motivationDetail = detailRow.MotivationDetailCode;

                            motivationDetailRow = (AMotivationDetailRow)FMainDS.AMotivationDetail.Rows.Find(
                                new object[] { FLedgerNumber, motivationGroup, motivationDetail });

                            if (motivationDetailRow != null)
                            {
                                if (partnerKey > 0)
                                {
                                    bool partnerIsMissingLink = false;

                                    detailRow.CostCentreCode = TRemote.MFinance.Gift.WebConnectors.RetrieveCostCentreCodeForRecipient(FLedgerNumber,
                                                                                                                                      partnerKey,
                                                                                                                                      detailRow.RecipientLedgerNumber,
                                                                                                                                      detailRow.DateEntered,
                                                                                                                                      motivationGroup,
                                                                                                                                      motivationDetail,
                                                                                                                                      out partnerIsMissingLink);
                                }
                                else
                                {
                                    if (motivationGroup != MFinanceConstants.MOTIVATION_GROUP_GIFT)
                                    {
                                        detailRow.RecipientDescription = motivationGroup;
                                    }
                                    else
                                    {
                                        detailRow.RecipientDescription = string.Empty;
                                    }

                                    detailRow.CostCentreCode = motivationDetailRow.CostCentreCode;
                                }

                                detailRow.AccountCode = motivationDetailRow.AccountCode;

                                if (FSETUseTaxDeductiblePercentageFlag && string.IsNullOrEmpty(motivationDetailRow.TaxDeductibleAccountCode))
                                {
                                    detailRow.TaxDeductibleAccountCode = string.Empty;

                                    string msg = String.Format(Catalog.GetString(
                                                                   "Gift: {0}, Detail: {1} has  Motivation Detail: {2} which has no Tax Deductible Account!" +
                                                                   "This can be added in Finance / Setup / Motivation Details.{3}{3}" +
                                                                   "Unless this is changed it will be impossible to assign a Tax Deductible Percentage to this gift."),
                                                               AGiftTransactionNumber,
                                                               detailRow.DetailNumber,
                                                               motivationDetail,
                                                               Environment.NewLine);
                                    MessageBox.Show(msg, Catalog.GetString(
                                                        "Copying Previous Split Gift"), MessageBoxButtons.OK, MessageBoxIcon.Warning);
                                }
                                else
                                {
                                    detailRow.TaxDeductibleAccountCode = motivationDetailRow.TaxDeductibleAccountCode;
                                }
                            }
                            else
                            {
                                string msg =
                                    String.Format(Catalog.GetString(
                                                      "Gift: {0}, Detail: {1} has Motivation Group and Detail codes ('{2} : {3}') not found in the database!"),
                                                  AGiftTransactionNumber,
                                                  detailRow.DetailNumber,
                                                  motivationGroup,
                                                  motivationDetail);
                                MessageBox.Show(msg, Catalog.GetString("Copying Previous Split Gift"), MessageBoxButtons.OK, MessageBoxIcon.Warning);

                                detailRow.TaxDeductible = false;
                            }
                        }

                        //______________________
                        //Handle tax fields
                        detailRow.TaxDeductiblePct = RetrieveTaxDeductiblePct((recipientIsValid ? detailRow.RecipientKey : 0),
                                                                              detailRow.TaxDeductible);

                        AGiftDetailRow giftDetails = (AGiftDetailRow)detailRow;
                        TaxDeductibility.UpdateTaxDeductibiltyAmounts(ref giftDetails);

                        //______________________
                        //Process comments
                        if (!FSETAutoCopyIncludeCommentsFlag)
                        {
                            detailRow.SetCommentOneTypeNull();
                            detailRow.SetCommentTwoTypeNull();
                            detailRow.SetCommentThreeTypeNull();
                            detailRow.SetGiftCommentOneNull();
                            detailRow.SetGiftCommentTwoNull();
                            detailRow.SetGiftCommentThreeNull();
                        }

                        detailRow.AcceptChanges();
                        detailRow.SetAdded();
                    }

                    //Add in the new records (latter two arguments put in to parallel recurring form)
                    FMainDS.AGiftDetail.Merge(GiftDetailTable, false, MissingSchemaAction.Ignore);

                    int indexOfLatestRow = FMainDS.AGiftDetail.Rows.Count - 1;

                    //Select last row added
                    if (SelectEndRow)
                    {
                        grdDetails.SelectRowInGrid(grdDetails.Rows.Count - 1);
                    }
                    else if (!SelectDetailRowByDataTableIndex(indexOfLatestRow))
                    {
                        if (!FFilterAndFindObject.IsActiveFilterEqualToBase)
                        {
                            MessageBox.Show(
                                MCommonResourcestrings.StrNewRecordIsFiltered,
                                MCommonResourcestrings.StrAddNewRecordTitle,
                                MessageBoxButtons.OK, MessageBoxIcon.Information);
                            FFilterAndFindObject.FilterPanelControls.ClearAllDiscretionaryFilters();

                            if (FFilterAndFindObject.FilterFindPanel.ShowApplyFilterButton != TUcoFilterAndFind.FilterContext.None)
                            {
                                FFilterAndFindObject.ApplyFilter();
                            }

                            SelectDetailRowByDataTableIndex(indexOfLatestRow);
                        }
                    }

                    ClearKeyMinistries();
                    cmbMotivationDetailCode.Clear();
                    mniRecipientHistory.Enabled = false;
                    btnDeleteAll.Enabled        = btnDelete.Enabled;
                    UpdateRecordNumberDisplay();
                    FLastDonor = -1;
                }
                else
                {
                    txtDetailDonorKey.FocusTextBoxPartAfterFindScreenCloses = false;
                    txtDetailGiftTransactionAmount.Focus();
                }

                FPetraUtilsObject.SetChangedFlag();
            }
            finally
            {
                this.Cursor = Cursors.Default;
                FAutoPopulatingGiftInProcess = false;
            }
        }
        /// <summary>
        /// Looks for gifts where the donor is anoymous but the gift is not marked as confidential and asks the user if they want to continue.
        /// (Make sure GetDataFromControls is called before this method so that AMainDS is up-to-date.)
        /// </summary>
        /// <param name="AMainDS"></param>
        public static bool CanContinueWithAnyAnonymousDonors(GiftBatchTDS AMainDS)
        {
            GiftBatchTDSAGiftDetailTable UnConfidentialGiftsWithAnonymousDonors = new GiftBatchTDSAGiftDetailTable();

            foreach (GiftBatchTDSAGiftDetailRow Row in AMainDS.AGiftDetail.Rows)
            {
                if (!Row.ConfidentialGiftFlag)
                {
                    PPartnerRow PartnerRow = (PPartnerRow)AMainDS.DonorPartners.Rows.Find(Row.DonorKey);

                    if ((PartnerRow != null) && PartnerRow.AnonymousDonor)
                    {
                        UnConfidentialGiftsWithAnonymousDonors.Rows.Add((object[])Row.ItemArray.Clone());
                    }
                }
            }

            if (UnConfidentialGiftsWithAnonymousDonors.Rows.Count > 0)
            {
                string Message = string.Empty;

                DataView dv = UnConfidentialGiftsWithAnonymousDonors.DefaultView;
                dv.Sort = GiftBatchTDSAGiftDetailTable.GetGiftTransactionNumberDBName() + " ASC";
                DataTable sortedDT = dv.ToTable();

                if (UnConfidentialGiftsWithAnonymousDonors.Rows.Count == 1)
                {
                    Message = Catalog.GetString(
                        "The gift listed below in this batch is not marked as confidential but the donor has asked to remain anonymous.");
                }
                else
                {
                    Message = Catalog.GetString(
                        "The gifts listed below in this batch are not marked as confidential but the donors have asked to remain anonymous.");
                }

                Message += "\n\n";

                foreach (DataRow UnConfidentialGifts in sortedDT.Rows)
                {
                    Message += Catalog.GetString("Batch: ") + UnConfidentialGifts[GiftBatchTDSAGiftDetailTable.GetBatchNumberDBName()] + "; " +
                               Catalog.GetString("Gift: ") + UnConfidentialGifts[GiftBatchTDSAGiftDetailTable.GetGiftTransactionNumberDBName()] +
                               "; " +
                               Catalog.GetString("Donor: ") + UnConfidentialGifts[GiftBatchTDSAGiftDetailTable.GetDonorNameDBName()] + " (" +
                               UnConfidentialGifts[GiftBatchTDSAGiftDetailTable.GetDonorKeyDBName()] + ")\n";
                }

                Message += "\n" + Catalog.GetString("Do you want to continue with posting anyway?");

                if (MessageBox.Show(
                        Message, Catalog.GetString("Anonymous Donor Warning"), MessageBoxButtons.YesNo, MessageBoxIcon.Warning)
                    == DialogResult.No)
                {
                    return false;
                }
            }

            return true;
        }
Example #33
0
        /// <summary>
        /// Import a transactions file or a clipboard equivalent
        /// </summary>
        /// <param name="ACurrentBatchRow">The batch to import to</param>
        /// <param name="AImportSource">The import source - eg File or Clipboard</param>
        /// <returns>True if the import was successful</returns>
        public bool ImportTransactions(AGiftBatchRow ACurrentBatchRow, TGiftImportDataSourceEnum AImportSource)
        {
            bool           ok = false;
            bool           RefreshGUIAfterImport = false;
            OpenFileDialog dialog      = null;
            Boolean        IsPlainText = false;

            if (FPetraUtilsObject.HasChanges)
            {
                // saving failed, therefore do not try to import
                MessageBox.Show(Catalog.GetString("Please save any changes before calling this function!"), Catalog.GetString(
                                    "Gift Import"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(false);
            }

            if ((ACurrentBatchRow == null) || (ACurrentBatchRow.BatchStatus != MFinanceConstants.BATCH_UNPOSTED))
            {
                MessageBox.Show(Catalog.GetString("Please select an unposted batch to import transactions."), Catalog.GetString(
                                    "Gift Import"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(false);
            }

            if (ACurrentBatchRow.LastGiftNumber > 0)
            {
                if (MessageBox.Show(Catalog.GetString(
                                        "The current batch already contains some gift transactions.  Do you really want to add more transactions to this batch?"),
                                    Catalog.GetString("Gift Transaction Import"),
                                    MessageBoxButtons.YesNo,
                                    MessageBoxIcon.Question,
                                    MessageBoxDefaultButton.Button2) == DialogResult.No)
                {
                    return(false);
                }
            }

            FdlgSeparator = new TDlgSelectCSVSeparator(false);
            FdlgSeparator.DateMayBeInteger = TUserDefaults.GetBooleanDefault(MCommonConstants.USERDEFAULT_IMPORTEDDATESMAYBEINTEGERS, false);

            if (AImportSource == TGiftImportDataSourceEnum.FromClipboard)
            {
                string importString = Clipboard.GetText(TextDataFormat.UnicodeText);

                if ((importString == null) || (importString.Length == 0))
                {
                    MessageBox.Show(Catalog.GetString("Please first copy data from your spreadsheet application!"),
                                    Catalog.GetString("Failure"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return(false);
                }

                FdlgSeparator.CSVData = importString;
            }
            else if (AImportSource == TGiftImportDataSourceEnum.FromFile)
            {
                dialog = new OpenFileDialog();

                string exportPath = TClientSettings.GetExportPath();
                string fullPath   = TUserDefaults.GetStringDefault("Imp Filename",
                                                                   exportPath + Path.DirectorySeparatorChar + "import.csv");
                TImportExportDialogs.SetOpenFileDialogFilePathAndName(dialog, fullPath, exportPath);

                dialog.Title  = Catalog.GetString("Import Transactions from CSV File");
                dialog.Filter = Catalog.GetString("Gift Transactions files (*.csv)|*.csv|Text Files (*.txt)|*.txt");

                // This call fixes Windows7 Open File Dialogs.  It must be the line before ShowDialog()
                TWin7FileOpenSaveDialog.PrepareDialog(Path.GetFileName(fullPath));

                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    Boolean fileCanOpen = FdlgSeparator.OpenCsvFile(dialog.FileName);

                    if (!fileCanOpen)
                    {
                        MessageBox.Show(Catalog.GetString("Unable to open file."),
                                        Catalog.GetString("Gift Import"),
                                        MessageBoxButtons.OK,
                                        MessageBoxIcon.Stop);
                        return(false);
                    }

                    IsPlainText = (Path.GetExtension(dialog.FileName).ToLower() == ".txt");
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                // unknown source!!  The following need a value...
                return(false);
            }

            String impOptions       = TUserDefaults.GetStringDefault("Imp Options", ";" + TDlgSelectCSVSeparator.NUMBERFORMAT_AMERICAN);
            String dateFormatString = TUserDefaults.GetStringDefault("Imp Date", "MDY");

            FdlgSeparator.DateFormat        = dateFormatString;
            FdlgSeparator.NumberFormat      = (impOptions.Length > 1) ? impOptions.Substring(1) : TDlgSelectCSVSeparator.NUMBERFORMAT_AMERICAN;
            FdlgSeparator.SelectedSeparator = StringHelper.GetCSVSeparator(FdlgSeparator.FileContent) ??
                                              ((impOptions.Length > 0) ? impOptions.Substring(0, 1) : ";");

            if (IsPlainText || (FdlgSeparator.ShowDialog() == DialogResult.OK))
            {
                Hashtable requestParams = new Hashtable();

                requestParams.Add("ALedgerNumber", FLedgerNumber);
                requestParams.Add("Delimiter", FdlgSeparator.SelectedSeparator);
                requestParams.Add("DateFormatString", FdlgSeparator.DateFormat);
                requestParams.Add("NumberFormat", FdlgSeparator.NumberFormat);
                requestParams.Add("NewLine", Environment.NewLine);

                bool Repeat = true;

                while (Repeat)
                {
                    Repeat = false;

                    TVerificationResultCollection AMessages = new TVerificationResultCollection();
                    GiftBatchTDSAGiftDetailTable  NeedRecipientLedgerNumber = new GiftBatchTDSAGiftDetailTable();

                    Thread ImportThread = new Thread(() => ImportGiftTransactions(
                                                         requestParams,
                                                         FdlgSeparator.FileContent,
                                                         ACurrentBatchRow.BatchNumber,
                                                         out AMessages,
                                                         out ok,
                                                         out RefreshGUIAfterImport,
                                                         out NeedRecipientLedgerNumber));

                    using (TProgressDialog ImportDialog = new TProgressDialog(ImportThread))
                    {
                        ImportDialog.ShowDialog();
                    }

                    // if the import contains gifts with Motivation Group 'GIFT' and that have a Family recipient with no Gift Destination
                    // then the import will have failed and we need to alert the user
                    int numberOfMissingGiftDestinations = NeedRecipientLedgerNumber.Rows.Count;

                    if (numberOfMissingGiftDestinations == 0)
                    {
                        if (TVerificationHelper.ResultsContainErrorCode(AMessages, PetraErrorCodes.ERR_DB_SERIALIZATION_EXCEPTION))
                        {
                            TConcurrentServerTransactions.ShowTransactionSerializationExceptionDialog();
                        }
                        else
                        {
                            ShowMessages(AMessages);
                        }
                    }

                    if (numberOfMissingGiftDestinations > 0)
                    {
                        bool offerToRunImportAgain           = true;
                        int  currentMissingGiftDestinationNo = 1;

                        // for each gift in which the recipient needs a Git Destination
                        foreach (GiftBatchTDSAGiftDetailRow Row in NeedRecipientLedgerNumber.Rows)
                        {
                            //Lookup the partner shortname
                            string        partnerShortName = string.Empty;
                            TPartnerClass partnerClass;

                            if (TServerLookup.TMPartner.GetPartnerShortName(Row.RecipientKey, out partnerShortName, out partnerClass))
                            {
                                Row.RecipientDescription = partnerShortName;
                            }

                            if (MessageBox.Show(string.Format(
                                                    Catalog.GetString(
                                                        "Error: {0:0000} of {1:0000} - Recipient '{2}' ({3}) has no Gift Destination assigned."),
                                                    currentMissingGiftDestinationNo, numberOfMissingGiftDestinations, Row.RecipientDescription,
                                                    Row.RecipientKey) +
                                                "\n\n" +
                                                Catalog.GetString("Do you want to assign a Gift Destination to this partner now?"),
                                                Catalog.GetString("Gift Import Cancelled"), MessageBoxButtons.YesNo, MessageBoxIcon.Warning)
                                == DialogResult.Yes)
                            {
                                // allow the user to assign a Gift Destingation
                                TFrmGiftDestination GiftDestinationForm = new TFrmGiftDestination(FPetraUtilsObject.GetForm(), Row.RecipientKey);
                                GiftDestinationForm.ShowDialog();
                            }
                            else
                            {
                                offerToRunImportAgain = false;
                            }

                            currentMissingGiftDestinationNo++;
                        }

                        // if the user has clicked yes to assigning Gift Destinations then offer to restart the import
                        if (offerToRunImportAgain &&
                            (MessageBox.Show(Catalog.GetString("Would you like to import these Gift Transactions again?"),
                                             Catalog.GetString("Gift Import"), MessageBoxButtons.YesNo, MessageBoxIcon.Question,
                                             MessageBoxDefaultButton.Button1)
                             == DialogResult.Yes))
                        {
                            Repeat = true;
                        }
                    }
                }
            }

            // We save the defaults even if ok is false - because the client will probably want to try and import
            //   the same file again after correcting any errors
            if (!IsPlainText)
            {
                SaveUserDefaults(dialog);
            }

            if (ok)
            {
                MessageBox.Show(Catalog.GetString("Your data was imported successfully!"),
                                Catalog.GetString("Gift Import"),
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);
            }

            if (ok || RefreshGUIAfterImport)
            {
                FMyUserControl.LoadBatchesForCurrentYear();
                FPetraUtilsObject.DisableSaveButton();
                return(true);        // This completes the refresh
            }

            return(false);
        }