/// <summary>
        /// Build the dynamic edit controls for this file format.
        /// </summary>
        /// <param name="fileFormat">The file format whose controls need to be built.</param>
        /// <param name="SetValues">Whether or not to set the initial values.</param>
        protected void BuildDynamicControls(ImageCashLetterFileFormat fileFormat, bool SetValues)
        {
            FileFormatEntityTypeId = fileFormat.EntityTypeId;

            fileFormat.LoadAttributes();
            phEditAttributes.Controls.Clear();
            Rock.Attribute.Helper.AddEditControls(fileFormat, phEditAttributes, SetValues, BlockValidationGroup, new List <string> {
                "Active", "Order"
            }, false, 2);
            foreach (var tb in phAttributes.ControlsOfTypeRecursive <TextBox>())
            {
                tb.AutoCompleteType           = AutoCompleteType.Disabled;
                tb.Attributes["autocomplete"] = "off";
            }
        }
        /// <summary>
        /// Gets the bundle control record (type 70).
        /// </summary>
        /// <param name="fileFormat">The file format that contains the configuration to use.</param>
        /// <param name="records">The existing records in the bundle.</param>
        /// <returns>A BundleControl record.</returns>
        protected virtual X937.Records.BundleControl GetBundleControl(ImageCashLetterFileFormat fileFormat, List <X937.Record> records)
        {
            var checkDetailRecords = records.Where(r => r.GetType() == typeof(X937.Records.CheckDetail))
                                     .Cast <X937.Records.CheckDetail>();
            var imageViewRecords = records.Where(r => r.GetType() == typeof(X937.Records.ImageViewDetail) || r.GetType() == typeof(X937.Records.ImageViewData));

            var control = new X937.Records.BundleControl
            {
                ItemCount            = checkDetailRecords.Count(),
                TotalAmount          = checkDetailRecords.Sum(r => r.ItemAmount),
                MICRValidTotalAmount = checkDetailRecords.Sum(r => r.ItemAmount),
                ImageCount           = imageViewRecords.Count()
            };

            return(control);
        }
        /// <summary>
        /// Gets the file control record (type 99).
        /// </summary>
        /// <param name="fileFormat">The file format that contains the configuration to use.</param>
        /// <param name="records">The existing records in the file.</param>
        /// <returns>A FileControl record.</returns>
        protected virtual X937.Records.FileControl GetFileControlRecord(ImageCashLetterFileFormat fileFormat, List <X937.Record> records)
        {
            var detailRecords = records.Where(r => r.GetType() == typeof(X937.Records.CheckDetail))
                                .Cast <X937.Records.CheckDetail>();

            var control = new X937.Records.FileControl
            {
                CashLetterCount                   = records.Count(r => r.GetType() == typeof(X937.Records.CashLetterHeader)),
                TotalRecordCount                  = records.Count + 1,
                TotalItemCount                    = detailRecords.Count(),
                TotalAmount                       = detailRecords.Sum(c => c.ItemAmount),
                ImmediateOriginContactName        = GetAttributeValue(fileFormat, "ContactName"),
                ImmediateOriginContactPhoneNumber = GetAttributeValue(fileFormat, "ContactPhone")
            };

            return(control);
        }
        /// <summary>
        /// Gets the item detail records (type 25, 26, etc.)
        /// </summary>
        /// <param name="fileFormat">The file format that contains the configuration to use.</param>
        /// <param name="transaction">The transaction being deposited.</param>
        /// <returns>A collection of records.</returns>
        protected virtual List <X937.Record> GetItemDetailRecords(ImageCashLetterFileFormat fileFormat, FinancialTransaction transaction)
        {
            var accountNumber = Rock.Security.Encryption.DecryptString(GetAttributeValue(fileFormat, "AccountNumber"));
            var routingNumber = Rock.Security.Encryption.DecryptString(GetAttributeValue(fileFormat, "RoutingNumber"));

            //
            // Parse the MICR data from the transaction.
            //
            var micr = new Micr(Rock.Security.Encryption.DecryptString(transaction.CheckMicrEncrypted));
            var transactionRoutingNumber = micr.GetField(5);

            //
            // Get the Check Detail record (type 25).
            //
            var detail = new X937.Records.CheckDetail
            {
                PayorBankRoutingNumber           = transactionRoutingNumber.Substring(0, 8),
                PayorBankRoutingNumberCheckDigit = transactionRoutingNumber.Substring(8, 1),
                OnUs = micr.GetField(3) + "/" + micr.GetField(2),
                ExternalProcessingCode = micr.GetField(6),
                AuxiliaryOnUs          = micr.GetField(7),
                ItemAmount             = transaction.TotalAmount,
                ClientInstitutionItemSequenceNumber = accountNumber,
                DocumentationTypeIndicator          = "G",
                BankOfFirstDepositIndicator         = "Y",
                CheckDetailRecordAddendumCount      = 1
            };

            //
            // Get the Addendum A record (type 26).
            //
            var detailA = new X937.Records.CheckDetailAddendumA
            {
                RecordNumber = 1,
                BankOfFirstDepositRoutingNumber       = routingNumber,
                BankOfFirstDepositBusinessDate        = DateTime.Now,
                TruncationIndicator                   = "N",
                BankOfFirstDepositConversionIndicator = "2",
                BankOfFirstDepositCorrectionIndicator = "0"
            };

            return(new List <X937.Record> {
                detail, detailA
            });
        }
        /// <summary>
        /// Gets the bundle header record (type 20).
        /// </summary>
        /// <param name="fileFormat">The file format that contains the configuration to use.</param>
        /// <param name="bundleIndex">Number of existing bundle records in the cash letter.</param>
        /// <returns>A BundleHeader record.</returns>
        protected virtual X937.Records.BundleHeader GetBundleHeader(ImageCashLetterFileFormat fileFormat, int bundleIndex)
        {
            var routingNumber = Rock.Security.Encryption.DecryptString(GetAttributeValue(fileFormat, "RoutingNumber"));

            var header = new X937.Records.BundleHeader
            {
                CollectionTypeIndicator        = 1,
                DestinationRoutingNumber       = routingNumber,
                ClientInstitutionRoutingNumber = routingNumber,
                BusinessDate   = DateTime.Now,
                CreationDate   = DateTime.Now,
                ID             = string.Empty,
                SequenceNumber = (bundleIndex + 1).ToString(),
                CycleNumber    = string.Empty,
                ReturnLocationRoutingNumber = routingNumber
            };

            return(header);
        }
        /// <summary>
        /// Gets the cash letter control record (type 90).
        /// </summary>
        /// <param name="fileFormat">The file format that contains the configuration to use.</param>
        /// <param name="records">Existing records in the cash letter.</param>
        /// <returns>A CashLetterControl record.</returns>
        protected virtual X937.Records.CashLetterControl GetCashLetterControlRecord(ImageCashLetterFileFormat fileFormat, List <X937.Record> records)
        {
            var bundleHeaderRecords = records.Where(r => r.GetType() == typeof(X937.Records.BundleHeader));
            var checkDetailRecords  = records.Where(r => r.GetType() == typeof(X937.Records.CheckDetail))
                                      .Cast <X937.Records.CheckDetail>();
            var imageRecords     = records.Where(r => r.GetType() == typeof(X937.Records.ImageViewDetail) || r.GetType() == typeof(X937.Records.ImageViewData));
            var organizationName = Rock.Web.Cache.GlobalAttributesCache.Value("OrganizationName");

            var control = new X937.Records.CashLetterControl
            {
                BundleCount        = bundleHeaderRecords.Count(),
                ItemCount          = checkDetailRecords.Count(),
                TotalAmount        = checkDetailRecords.Sum(c => c.ItemAmount),
                ImageCount         = imageRecords.Count(),
                ECEInstitutionName = organizationName
            };

            return(control);
        }
        /// <summary>
        /// Shows the edit panel.
        /// </summary>
        /// <param name="fileFormatId">The file format identifier.</param>
        public void ShowDetail(int fileFormatId)
        {
            var rockContext = new RockContext();
            ImageCashLetterFileFormat fileFormat = null;
            bool editAllowed = IsUserAuthorized(Authorization.EDIT);

            if (fileFormatId != 0)
            {
                fileFormat  = new ImageCashLetterFileFormatService(rockContext).Get(fileFormatId);
                editAllowed = editAllowed || fileFormat.IsAuthorized(Authorization.EDIT, CurrentPerson);
                pdAuditDetails.SetEntity(fileFormat, ResolveRockUrl("~"));
            }

            if (fileFormat == null)
            {
                fileFormat = new ImageCashLetterFileFormat {
                    Id = 0
                };
                fileFormat.FileNameTemplate = "{{ 'Now' | Date:'yyyyMMddHHmm.x937' }}";
                // hide the panel drawer that show created and last modified dates
                pdAuditDetails.Visible = false;
            }

            FileFormatId = fileFormat.Id;

            bool readOnly = false;

            nbEditModeMessage.Text = string.Empty;
            if (!editAllowed || !IsUserAuthorized(Authorization.EDIT))
            {
                readOnly = true;
                nbEditModeMessage.Text = EditModeMessage.ReadOnlyEditActionNotAllowed("File Format");
            }

            if (readOnly)
            {
                ShowReadonlyDetails(fileFormat);
            }
            else
            {
                ShowEditDetails(fileFormat);
            }
        }
Example #8
0
        /// <summary>
        /// Gets the attribute value for the file format
        /// </summary>
        /// <param name="fileFormat">The file format.</param>
        /// <param name="key">The key.</param>
        /// <returns></returns>
        public string GetAttributeValue(ImageCashLetterFileFormat fileFormat, string key)
        {
            if (fileFormat.AttributeValues == null)
            {
                fileFormat.LoadAttributes();
            }

            var values = fileFormat.AttributeValues;

            if (values != null && values.ContainsKey(key))
            {
                var keyValues = values[key];
                if (keyValues != null)
                {
                    return(keyValues.Value);
                }
            }

            return(string.Empty);
        }
        /// <summary>
        /// Gets the file header record (type 01).
        /// </summary>
        /// <param name="fileFormat">The file format that contains the configuration to use.</param>
        /// <returns>A FileHeader record.</returns>
        protected virtual X937.Records.FileHeader GetFileHeaderRecord(ImageCashLetterFileFormat fileFormat)
        {
            var destinationRoutingNumber = Rock.Security.Encryption.DecryptString(GetAttributeValue(fileFormat, "RoutingNumber"));
            var originRoutingNumber      = Rock.Security.Encryption.DecryptString(GetAttributeValue(fileFormat, "AccountNumber"));
            var header = new X937.Records.FileHeader
            {
                FileTypeIndicator = GetAttributeValue(fileFormat, "TestMode").AsBoolean(true) ? "T" : "P",
                ImmediateDestinationRoutingNumber = destinationRoutingNumber,
                ImmediateOriginRoutingNumber      = originRoutingNumber,
                FileCreationDateTime     = DateTime.Now,
                ResendIndicator          = "N",
                ImmediateDestinationName = GetAttributeValue(fileFormat, "DestinationName"),
                ImmediateOriginName      = GetAttributeValue(fileFormat, "OriginName"),
                FileIdModifier           = "1", // TODO: Need some way to track this and reset each day.
                CountryCode = "US",             /* Should be safe, X9.37 is only used in the US as far as I know. */
                UserField   = string.Empty
            };

            return(header);
        }
        /// <summary>
        /// Gets all the bundle records in required for the transactions specified.
        /// </summary>
        /// <param name="fileFormat">The file format that contains the configuration to use.</param>
        /// <param name="transactions">The transactions to be exported.</param>
        /// <returns>A collection of records that identify all the exported transactions.</returns>
        protected virtual List <X937.Record> GetBundleRecords(ImageCashLetterFileFormat fileFormat, List <FinancialTransaction> transactions)
        {
            var records = new List <X937.Record>();

            for (int bundleIndex = 0; (bundleIndex * MaxItemsPerBundle) < transactions.Count(); bundleIndex++)
            {
                var bundleRecords      = new List <X937.Record>();
                var bundleTransactions = transactions.Skip(bundleIndex * MaxItemsPerBundle)
                                         .Take(MaxItemsPerBundle)
                                         .ToList();

                //
                // Add the bundle header for this set of transactions.
                //
                bundleRecords.Add(GetBundleHeader(fileFormat, bundleIndex));

                //
                // Allow subclasses to provide credit detail records (type 61) if they want.
                //
                bundleRecords.AddRange(GetCreditDetailRecords(fileFormat, bundleIndex, bundleTransactions));

                //
                // Add records for each transaction in the bundle.
                //
                foreach (var transaction in bundleTransactions)
                {
                    bundleRecords.AddRange(GetItemRecords(fileFormat, transaction));
                }

                //
                // Add the bundle control record.
                //
                bundleRecords.Add(GetBundleControl(fileFormat, bundleRecords));

                records.AddRange(bundleRecords);
            }

            return(records);
        }
        /// <summary>
        /// Gets the cash letter header record (type 10).
        /// </summary>
        /// <param name="fileFormat">The file format that contains the configuration to use.</param>
        /// <returns>A CashLetterHeader record.</returns>
        protected virtual X937.Records.CashLetterHeader GetCashLetterHeaderRecord(ImageCashLetterFileFormat fileFormat)
        {
            var routingNumber = Rock.Security.Encryption.DecryptString(GetAttributeValue(fileFormat, "RoutingNumber"));
            var contactName   = GetAttributeValue(fileFormat, "ContactName");
            var contactPhone  = GetAttributeValue(fileFormat, "ContactPhone");

            var header = new X937.Records.CashLetterHeader
            {
                CollectionTypeIndicator        = 1,
                DestinationRoutingNumber       = routingNumber,
                ClientInstitutionRoutingNumber = routingNumber,
                BusinessDate               = DateTime.Now, // TODO: We might need to ask the user this and pass it in.
                CreationDateTime           = DateTime.Now,
                RecordTypeIndicator        = "I",
                DocumentationTypeIndicator = "G",
                ID = "TODO", // TODO: Fix this, waiting for feedback from bank.
                OriginatorContactName        = contactName,
                OriginatorContactPhoneNumber = contactPhone
            };

            return(header);
        }
        /// <summary>
        /// Shows the edit details.
        /// </summary>
        /// <param name="fileFormat">The file format.</param>
        private void ShowEditDetails(ImageCashLetterFileFormat fileFormat)
        {
            if (fileFormat.Id == 0)
            {
                lActionTitle.Text = ActionTitle.Add("File Format");
            }
            else
            {
                lActionTitle.Text = fileFormat.Name.FormatAsHtmlTitle();
            }

            hlInactive.Visible = !fileFormat.IsActive;

            SetEditMode(true);

            tbName.Text             = fileFormat.Name;
            cbIsActive.Checked      = fileFormat.IsActive;
            tbDescription.Text      = fileFormat.Description;
            tbFileNameTemplate.Text = fileFormat.FileNameTemplate;
            cpFileFormatType.SetValue(fileFormat.EntityType != null ? fileFormat.EntityType.Guid.ToString().ToUpper() : string.Empty);

            BuildDynamicControls(fileFormat, true);
        }
        /// <summary>
        /// Shows the readonly details.
        /// </summary>
        /// <param name="fileFormat">The file format.</param>
        private void ShowReadonlyDetails(ImageCashLetterFileFormat fileFormat)
        {
            SetEditMode(false);

            lActionTitle.Text           = fileFormat.Name.FormatAsHtmlTitle();
            hlInactive.Visible          = !fileFormat.IsActive;
            lFileFormatDescription.Text = fileFormat.Description;

            var descriptionList = new DescriptionList();

            if (fileFormat.EntityType != null)
            {
                descriptionList.Add("File Format Type", fileFormat.EntityType.Name);
            }

            descriptionList.Add("File Name Template", fileFormat.FileNameTemplate);

            lblMainDetails.Text = descriptionList.Html;

            phAttributes.Controls.Clear();
            Rock.Attribute.Helper.AddDisplayControls(fileFormat, phAttributes, new List <string> {
                "Active", "Order"
            });
        }
        /// <summary>
        /// Gets the image record for a specific transaction image (type 50 and 52).
        /// </summary>
        /// <param name="fileFormat">The file format that contains the configuration to use.</param>
        /// <param name="transaction">The transaction being deposited.</param>
        /// <param name="image">The check image scanned by the scanning application.</param>
        /// <param name="isFront">if set to <c>true</c> [is front].</param>
        /// <returns>A collection of records.</returns>
        protected virtual List <X937.Record> GetImageRecords(ImageCashLetterFileFormat fileFormat, FinancialTransaction transaction, FinancialTransactionImage image, bool isFront)
        {
            var routingNumber = Rock.Security.Encryption.DecryptString(GetAttributeValue(fileFormat, "RoutingNumber"));
            var accountNumber = Rock.Security.Encryption.DecryptString(GetAttributeValue(fileFormat, "AccountNumber"));

            //
            // Get the Image View Detail record (type 50).
            //
            var detail = new X937.Records.ImageViewDetail
            {
                ImageIndicator                 = 1,
                ImageCreatorRoutingNumber      = routingNumber,
                ImageCreatorDate               = image.CreatedDateTime ?? DateTime.Now,
                ImageViewFormatIndicator       = 0,
                CompressionAlgorithmIdentifier = 0,
                SideIndicator             = isFront ? 0 : 1,
                ViewDescriptor            = 0,
                DigitalSignatureIndicator = 0
            };

            //
            // Get the Image View Data record (type 51).
            //
            var data = new X937.Records.ImageViewData
            {
                InstitutionRoutingNumber            = routingNumber,
                BundleBusinessDate                  = DateTime.Now,
                ClientInstitutionItemSequenceNumber = accountNumber,
                ClippingOrigin = 0,
                ImageData      = image.BinaryFile.ContentStream.ReadBytesToEnd()
            };

            return(new List <X937.Record> {
                detail, data
            });
        }
Example #15
0
 /// <summary>
 /// Exports a collection of batches to a binary file that can be downloaded by the user
 /// and sent to their financial institution. The returned BinaryFile should not have been
 /// saved to the database yet.
 /// </summary>
 /// <param name="fileFormat">The <see cref="ImageCashLetterFileFormat" /> that is being used to export this data.</param>
 /// <param name="batches">The list of batches whose data needs to be exported.</param>
 /// <param name="errorMessages">On return will contain a list of error messages if not empty.</param>
 /// <returns>A <see cref="Stream" /> of data that should be downloaded to the user in a file.</returns>
 public abstract Stream ExportBatches(ImageCashLetterFileFormat fileFormat, List <FinancialBatch> batches, out List <string> errorMessages);
 /// <summary>
 /// Gets the credit detail deposit record (type 61).
 /// </summary>
 /// <param name="fileFormat">The file format that contains the configuration to use.</param>
 /// <param name="bundleIndex">Number of existing bundle records in the cash letter.</param>
 /// <param name="transactions">The transactions associated with this deposit.</param>
 /// <returns>A collection of records.</returns>
 protected virtual List <X937.Record> GetCreditDetailRecords(ImageCashLetterFileFormat fileFormat, int bundleIndex, List <FinancialTransaction> transactions)
 {
     return(new List <X937.Record>());
 }
Example #17
0
 /// <summary>
 /// Imports batches from a data file. The batches should not be added to the database
 /// but only initialized.
 /// </summary>
 /// <param name="fileFormat">The <see cref="ImageCashLetterFileFormat" /> that is being used to import this data.</param>
 /// <param name="content">A <see cref="Stream"/> that can be used to access the file data.</param>
 /// <param name="errorMessages">On return will contain a list of error messages if not empty.</param>
 /// <returns>A list of FinancialBatches that are ready to be saved to the database.</returns>
 public virtual List <FinancialBatch> ImportBatches(ImageCashLetterFileFormat fileFormat, Stream content, out List <string> errorMessages)
 {
     throw new NotImplementedException("Importing of batches is not supported by this component.");
 }