Skip to content

Instantly share code, notes, and snippets.

@ryanoshea
Created December 20, 2019 16:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ryanoshea/e86ad2f9c5b01c16783559de5c23994a to your computer and use it in GitHub Desktop.
Save ryanoshea/e86ad2f9c5b01c16783559de5c23994a to your computer and use it in GitHub Desktop.
X9Document Authoring Example

Authoring an X9Document

Below is an example of producing an (incomplete) X9Document by creating most of the required records and setting a few field values. This example leaves out a few fields and may contain a few mistakes, but the general pattern should be apparent at least. Each X9Document starts completely empty, and each X9Record or additional X9DocumentComponent must be initialized and filled out.

public static X9Document Create(List<CheckInfo> checks)
{
    DateTimeOffset createTime = DateTimeOffset.Now;
    DateTimeOffset busDate = DateTimeOffset.Now;
    string custId = "938476";
    int numRecords = 0;
    int numItems = 0;
    decimal totalAmount = 0;

    var doc = new X9Document
    {
        Header = new FileHeaderRecord(),
        Trailer = new FileTrailerRecord()
    };
    numRecords += 2;

    // Configure header
    doc.Header.TestFileIndicator.SetValue(true);
    doc.Header.ImmediateOriginRoutingNumber.SetValue("044000037");
    doc.Header.FileCreationDate.SetValue(createTime); // The same DateTimeOffset can be passed into a date & time
    doc.Header.FileCreationTime.SetValue(createTime); // field separately, and the appropriate values will be set
    doc.Header.ResendIndicator.SetValue(false);
    doc.Header.ImmediateOriginName.SetValue("MY COMPANY");

    // Create a single deposit
    var dep = new X9Deposit
    {
        CashLetterHeader = new CashLetterHeaderRecord(),
        CashLetterTrailer = new CashLetterTrailerRecord()
    };
    numRecords += 2;

    dep.CashLetterHeader.CashLetterBusinessDate.SetValue(busDate);
    dep.CashLetterHeader.UniqueCustomerIdentifier.SetValue(custId);
    dep.CashLetterHeader.CashLetterCreationDate.SetValue(createTime);
    dep.CashLetterHeader.CashLetterCreationTime.SetValue(createTime);

    // Create a single bundle
    int bundleIdx = 0;
    decimal depositTotalAmount = 0;
    int depositNumItems = 0;
    int depositNumImages = 0;
        
    var bundle = new X9Bundle
    {
        Header = new BundleHeaderRecord(),
        Trailer = new BundleTrailerRecord()
    };
    numRecords += 2;

    bundle.Header.UniqueCustomerIdentifier.SetValue(custId);
    bundle.Header.BundleBusinessDate.SetValue(busDate);
    bundle.Header.BundleCreationDate.SetValue(createTime);
    bundle.Header.BundleSequenceNumber.SetValue(bundleIdx);

    // Create a few checks based on the ones passed in
    int bundleNumImages = 0;
    decimal bundleTotalAmount = 0;
    foreach (CheckInfo depositItemInfo in checks)
    {
        var depItem = new X9DepositItem()
        {
            CheckDetail = new CheckDetailRecord()
        };
        numRecords += 1;

        depItem.CheckDetail.Amount.SetValue(depositItemInfo.Amount);
        // You'd also set the various MICR fields here

        // Add images for the check

        // Front first
        var frontImageRecord = new X9DepositItemImage()
        {
            ImageViewDetail = new ImageViewDetailRecord(),
            ImageViewData = new ImageViewDataRecord()
        };
        numRecords += 2;
        byte[] frontImageBytes;
        using (FileStream frontImageFile = File.OpenRead(depositItemInfo.FrontImagePath))
        {
            frontImageBytes = new byte[frontImageFile.Length];
            using (MemoryStream byteStream = new MemoryStream(frontImageBytes))
            {
                frontImageFile.CopyTo(byteStream);
            }
        }
        frontImageRecord.ImageViewDetail.ViewSideIndicator.SetValue(0); // front
        frontImageRecord.ImageViewDetail.ImageRecreateIndicator.SetValue(1);
        frontImageRecord.ImageViewData.BundleBusinessDate.SetValue(busDate);
        frontImageRecord.ImageViewData.ImageData.SetImageBytes(frontImageBytes);
        frontImageRecord.ImageViewData.LengthOfImageData.SetValue(frontImageBytes.Length);
        depItem.Images.Add(frontImageRecord);
        bundleNumImages++;

        // Back
        var backImageRecord = new X9DepositItemImage()
        {
            ImageViewDetail = new ImageViewDetailRecord(),
            ImageViewData = new ImageViewDataRecord()
        };
        numRecords += 2;
        byte[] backImageBytes;
        using (FileStream backImageFile = File.OpenRead(depositItemInfo.BackImagePath))
        {
            backImageBytes = new byte[backImageFile.Length];
            using (MemoryStream byteStream = new MemoryStream(backImageBytes))
            {
                backImageFile.CopyTo(byteStream);
            }
        }
        backImageRecord.ImageViewDetail.ViewSideIndicator.SetValue(0); // front
        backImageRecord.ImageViewDetail.ImageRecreateIndicator.SetValue(1);
        backImageRecord.ImageViewData.BundleBusinessDate.SetValue(busDate);
        backImageRecord.ImageViewData.ImageData.SetImageBytes(backImageBytes);
        backImageRecord.ImageViewData.LengthOfImageData.SetValue(backImageBytes.Length);
        depItem.Images.Add(backImageRecord);
        bundleNumImages++;

        bundle.DepositItems.Add(depItem);
        bundleTotalAmount += depositItemInfo.Amount;
    }

    // Configure bundle trailer
    bundle.Trailer.ItemsWithinBundleCount.SetValue(bundle.DepositItems.Count);
    bundle.Trailer.ImagesWithinBundleCount.SetValue(bundleNumImages);
    bundle.Trailer.MicrValidTotalAmount.SetValue(bundleTotalAmount);

    dep.Bundles.Add(bundle);
    bundleIdx++;
    depositTotalAmount += bundleTotalAmount;
    depositNumItems += bundle.DepositItems.Count;
    depositNumImages += bundleNumImages;

    // Configure cash letter trailer
    dep.CashLetterTrailer.BundleCount.SetValue(bundleIdx);
    dep.CashLetterTrailer.ImagesWithinCashLetterCount.SetValue(depositNumImages);
    dep.CashLetterTrailer.ItemsWithinCashLetterCount.SetValue(depositNumItems);
    dep.CashLetterTrailer.CashLetterTotalAmount.SetValue(depositTotalAmount);

    numItems += depositNumItems;
    totalAmount += depositTotalAmount;

    doc.Deposits.Add(dep);

    // Configure file trailer
    doc.Trailer.CashLetterCount.SetValue(doc.Deposits.Count);
    doc.Trailer.TotalRecordCount.SetValue(numRecords);
    doc.Trailer.TotalFileAmount.SetValue(totalAmount);
    doc.Trailer.TotalItemCount.SetValue(numItems);

    return doc;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment