/// <summary> /// Shows the startup page. /// </summary> private void ShowStartupPage() { var rockConfig = RockConfig.Load(); lblExceptions.Visibility = Visibility.Collapsed; lblScanCheckWarningBadMicr.Visibility = Visibility.Collapsed; lblScanCheckWarningDuplicate.Visibility = Visibility.Collapsed; if (rockConfig.ScannerInterfaceType == RockConfig.InterfaceType.RangerApi && rockConfig.EnableRearImage) { lblBack.Visibility = Visibility.Visible; } else if (rockConfig.ScannerInterfaceType == RockConfig.InterfaceType.MICRImageRS232 && rockConfig.PromptToScanRearImage) { lblBack.Visibility = Visibility.Visible; } else { lblBack.Visibility = Visibility.Hidden; } this.ClearScannedDocHistory(); lblSomeBadScans.Visibility = Visibility.Collapsed; ExpectingMagTekBackScan = false; ScannedDocInfo sampleDocInfo = new ScannedDocInfo(); sampleDocInfo.CurrencyTypeValue = batchPage.CurrencyValueList.FirstOrDefault(a => a.Guid == RockConfig.Load().SourceTypeValueGuid.AsGuid()); DisplayScannedDocInfo(sampleDocInfo); gScannedChecksNavigation.Visibility = Visibility.Collapsed; btnDeleteItem.Visibility = Visibility.Collapsed; UpdateScanInstructions(); }
/// <summary> /// Shows the startup page. /// </summary> private void ShowStartupPage() { var rockConfig = RockConfig.Load(); HideUploadWarningPrompts(); lblExceptions.Visibility = Visibility.Collapsed; lblStartupInfo.Visibility = Visibility.Visible; lblNoItemsFound.Visibility = Visibility.Collapsed; lblScannerNotReady.Visibility = Visibility.Collapsed; ScannedDocInfo sampleDocInfo = new ScannedDocInfo(); sampleDocInfo.CurrencyTypeValue = batchPage.CurrencyValueList.FirstOrDefault(a => a.Guid == RockConfig.Load().SourceTypeValueGuid.AsGuid()); DisplayScannedDocInfo(sampleDocInfo); bool scanningChecks = RockConfig.Load().TenderTypeValueGuid.AsGuid() == Rock.Client.SystemGuid.DefinedValue.CURRENCY_TYPE_CHECK.AsGuid(); lblNoItemsFound.Content = string.Format("No {0} detected in scanner. Make sure {0} are properly in the feed tray.", scanningChecks ? "checks" : "items"); lblScanBackInstructions.Content = string.Format("Insert the {0} again facing the other direction to get an image of the back.", scanningChecks ? "check" : "item"); lblScanBackInstructions.Visibility = Visibility.Collapsed; if (RockConfig.Load().ScannerInterfaceType == RockConfig.InterfaceType.MICRImageRS232) { lblStartupInfo.Content = string.Format("Ready to scan next {0}.", scanningChecks ? "check" : "item"); // no need for a stop/start button when in MagTek mode btnStart.Visibility = Visibility.Hidden; btnStopScanning.Visibility = Visibility.Hidden; } else { btnStart.Visibility = Visibility.Visible; btnStopScanning.Visibility = Visibility.Visible; lblStartupInfo.Content = "Click Start to begin"; } }
/// <summary> /// Determines whether [is duplicate scan] [the specified scanned document]. /// </summary> /// <param name="scannedDoc">The scanned document.</param> /// <returns></returns> public static bool IsDuplicateScan(ScannedDocInfo scannedDoc) { if (!scannedDoc.IsCheck) { return(false); } if (scannedDoc.BadMicr) { return(false); } var uploadClient = EnsureUploadScanRestClient(); if (uploadClient == null) { var rockConfig = RockConfig.Load(); uploadClient = new RockRestClient(rockConfig.RockBaseUrl); uploadClient.Login(rockConfig.Username, rockConfig.Password); } var alreadyScanned = uploadClient.PostDataWithResult <string, bool>("api/FinancialTransactions/AlreadyScanned", scannedDoc.ScannedCheckMicrData); return(alreadyScanned); }
/// <summary> /// Handles the Click event of the btnSkipAndContinue control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param> private void btnSkipAndContinue_Click(object sender, RoutedEventArgs e) { HideUploadWarningPrompts(); this.ConfirmUploadBadScannedDoc = null; _itemsSkipped++; ShowUploadStats(); ResumeScanning(); }
/// <summary> /// Adds the scanned doc to a history of scanned docs, and shows info and status. /// </summary> /// <param name="scannedDocInfo">The scanned check info.</param> public void ShowScannedDocStatusAndUpload(ScannedDocInfo scannedDocInfo) { lblExceptions.Visibility = Visibility.Collapsed; DisplayScannedDocInfo(scannedDocInfo); var rockConfig = RockConfig.Load(); bool scanningChecks = rockConfig.TenderTypeValueGuid.AsGuid() == Rock.Client.SystemGuid.DefinedValue.CURRENCY_TYPE_CHECK.AsGuid(); // if they don't enable smart scan, don't warn about bad micr's. For example, they might be scanning a mixture of checks and envelopes if (rockConfig.EnableSmartScan) { if (scannedDocInfo.BadMicr) { if (rockConfig.ScannerInterfaceType == RockConfig.InterfaceType.RangerApi) { lblScanCheckWarningBadMicr.Content = @"Unable to read check information Click 'Skip' to reject this check and continue scanning. To retry this check, put the check back into the feed tray. Click 'Upload' to upload the check as-is. Click 'Stop' to reject this check and stop scanning."; } else { lblScanCheckWarningBadMicr.Content = @"Unable to read check information Click 'Skip' to reject this check. Click 'Upload' to upload the check as-is."; } } } else { // if Enable Smart Scan is disabled, upload even if there is a bad or missing MICR if (!scannedDocInfo.Upload) { scannedDocInfo.Upload = true; } } if (scannedDocInfo.Upload && IsDuplicateScan(scannedDocInfo)) { scannedDocInfo.Duplicate = true; scannedDocInfo.Upload = false; } if (scannedDocInfo.Upload) { this.UploadScannedItem(scannedDocInfo); if (_keepScanning) { ResumeScanning(); } } else { ShowUploadWarnings(scannedDocInfo); } }
/// <summary> /// Shows the upload warnings. /// </summary> private void ShowUploadWarnings(ScannedDocInfo scannedDocInfo) { var rockConfig = RockConfig.Load(); ConfirmUploadBadScannedDoc = scannedDocInfo; lblScanCheckWarningDuplicate.Visibility = scannedDocInfo.Duplicate ? Visibility.Visible : Visibility.Collapsed; lblScanCheckWarningBadMicr.Visibility = scannedDocInfo.BadMicr ? Visibility.Visible : Visibility.Collapsed; lblScanItemUploadSuccess.Visibility = Visibility.Collapsed; pnlPromptForUpload.Visibility = scannedDocInfo.Duplicate || scannedDocInfo.BadMicr ? Visibility.Visible : Visibility.Collapsed; btnStart.IsEnabled = false; btnStopScanning.IsEnabled = true; }
/// <summary> /// Displays the scanned document information. /// </summary> /// <param name="scannedDocInfo">The scanned document information.</param> private void DisplayScannedDocInfo(ScannedDocInfo scannedDocInfo) { if (scannedDocInfo.FrontImageData != null) { BitmapImage bitmapImageFront = new BitmapImage(); bitmapImageFront.BeginInit(); bitmapImageFront.StreamSource = new MemoryStream(scannedDocInfo.FrontImageData); bitmapImageFront.EndInit(); imgFront.Source = bitmapImageFront; Rock.Wpf.WpfHelper.FadeIn(imgFront, 100); lblFront.Visibility = Visibility.Visible; } else { lblFront.Visibility = Visibility.Hidden; imgFront.Source = null; } if (scannedDocInfo.BackImageData != null) { BitmapImage bitmapImageBack = new BitmapImage(); bitmapImageBack.BeginInit(); bitmapImageBack.StreamSource = new MemoryStream(scannedDocInfo.BackImageData); bitmapImageBack.EndInit(); imgBack.Source = bitmapImageBack; Rock.Wpf.WpfHelper.FadeIn(imgBack, 100); lblBack.Visibility = Visibility.Visible; colBackImage.Width = new GridLength(1, GridUnitType.Star); } else { imgBack.Source = null; lblBack.Visibility = Visibility.Hidden; colBackImage.Width = new GridLength(0, GridUnitType.Star); } if (scannedDocInfo.IsCheck) { pnlChecks.Visibility = Visibility.Visible; lblRoutingNumber.Content = scannedDocInfo.RoutingNumber ?? "--"; lblAccountNumber.Content = scannedDocInfo.AccountNumber ?? "--"; lblCheckNumber.Content = scannedDocInfo.CheckNumber ?? "--"; lblOtherData.Content = scannedDocInfo.OtherData; spOtherData.Visibility = !string.IsNullOrWhiteSpace(scannedDocInfo.OtherData) ? Visibility.Visible : Visibility.Collapsed; } else { pnlChecks.Visibility = Visibility.Collapsed; } }
/// <summary> /// Adds the scanned doc to a history of scanned docs, and shows info and status. /// </summary> /// <param name="scannedDocInfo">The scanned check info.</param> public void ShowScannedDocStatus(ScannedDocInfo scannedDocInfo) { lblExceptions.Visibility = Visibility.Collapsed; CurrentScannedDocInfo = scannedDocInfo; if (!ScannedDocInfoHistory.Contains(scannedDocInfo)) { ScannedDocInfoHistory.Add(scannedDocInfo); } if (ScannedDocInfoHistory.Count > 1) { gScannedChecksNavigation.Visibility = Visibility.Visible; } else { gScannedChecksNavigation.Visibility = Visibility.Collapsed; } NavigateTo(ScannedDocInfoHistory.Count - 1); ExpectingMagTekBackScan = false; var rockConfig = RockConfig.Load(); // If we have the front image and valid routing number, but not the back (and it's a MagTek). Inform them to scan the back; if (rockConfig.ScannerInterfaceType == RockConfig.InterfaceType.MICRImageRS232) { if ((imgFront.Source != null) && (imgBack.Source == null)) { if (rockConfig.PromptToScanRearImage) { if (scannedDocInfo.IsCheck && (scannedDocInfo.RoutingNumber.Length != 9 || string.IsNullOrWhiteSpace(scannedDocInfo.AccountNumber))) { ExpectingMagTekBackScan = false; lblScanInstructions.Content = "INFO: Ready to re-scan check"; } else { ExpectingMagTekBackScan = true; lblScanInstructions.Content = string.Format("INFO: Insert the {0} again facing the other direction to get an image of the back.", scannedDocInfo.IsCheck ? "check" : "item"); } } } else { UpdateScanInstructions(); } } }
/// <summary> /// Adds the scanned doc to a history of scanned docs, and shows info and status. /// </summary> /// <param name="scannedDocInfo">The scanned check info.</param> public void ShowScannedDocStatusAndUpload( ScannedDocInfo scannedDocInfo ) { lblExceptions.Visibility = Visibility.Collapsed; DisplayScannedDocInfo( scannedDocInfo ); var rockConfig = RockConfig.Load(); bool scanningChecks = rockConfig.TenderTypeValueGuid.AsGuid() == Rock.Client.SystemGuid.DefinedValue.CURRENCY_TYPE_CHECK.AsGuid(); // if they don't enable smart scan, don't warn about bad micr's. For example, they might be scanning a mixture of checks and envelopes if ( rockConfig.EnableSmartScan ) { if ( scannedDocInfo.BadMicr ) { if ( rockConfig.ScannerInterfaceType == RockConfig.InterfaceType.RangerApi ) { lblScanCheckWarningBadMicr.Content = @"Unable to read check information Click 'Skip' to reject this check and continue scanning. To retry this check, put the check back into the feed tray. Click 'Upload' to upload the check as-is. Click 'Stop' to reject this check and stop scanning."; } else { lblScanCheckWarningBadMicr.Content = @"Unable to read check information Click 'Skip' to reject this check. Click 'Upload' to upload the check as-is."; } } } else { // if Enable Smart Scan is disabled, upload even if there is a bad or missing MICR if ( !scannedDocInfo.Upload ) { scannedDocInfo.Upload = true; } } if ( scannedDocInfo.Upload && IsDuplicateScan( scannedDocInfo ) ) { scannedDocInfo.Duplicate = true; scannedDocInfo.Upload = false; } if ( scannedDocInfo.Upload ) { this.UploadScannedItem( scannedDocInfo ); if ( _keepScanning ) { ResumeScanning(); } } else { ShowUploadWarnings( scannedDocInfo ); } }
/// <summary> /// Displays the scanned document information. /// </summary> /// <param name="scannedDocInfo">The scanned document information.</param> private void DisplayScannedDocInfo( ScannedDocInfo scannedDocInfo ) { if ( scannedDocInfo.FrontImageData != null ) { BitmapImage bitmapImageFront = new BitmapImage(); bitmapImageFront.BeginInit(); bitmapImageFront.StreamSource = new MemoryStream( scannedDocInfo.FrontImageData ); bitmapImageFront.EndInit(); imgFront.Source = bitmapImageFront; lblFront.Visibility = Visibility.Visible; } else { lblFront.Visibility = Visibility.Hidden; imgFront.Source = null; } if ( scannedDocInfo.BackImageData != null ) { BitmapImage bitmapImageBack = new BitmapImage(); bitmapImageBack.BeginInit(); bitmapImageBack.StreamSource = new MemoryStream( scannedDocInfo.BackImageData ); bitmapImageBack.EndInit(); imgBack.Source = bitmapImageBack; lblBack.Visibility = Visibility.Visible; } else { imgBack.Source = null; lblBack.Visibility = Visibility.Hidden; } if ( scannedDocInfo.IsCheck ) { pnlChecks.Visibility = Visibility.Visible; lblRoutingNumber.Content = scannedDocInfo.RoutingNumber ?? "--"; lblAccountNumber.Content = scannedDocInfo.AccountNumber ?? "--"; lblCheckNumber.Content = scannedDocInfo.CheckNumber ?? "--"; } else { pnlChecks.Visibility = Visibility.Collapsed; } }
/// <summary> /// Handles the MicrDataReceived event of the micrImage control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> public void micrImage_MicrDataReceived( object sender, System.EventArgs e ) { var currentPage = Application.Current.MainWindow.Content; if ( currentPage != this ) { // only accept scans when the scanning page is showing batchPage.micrImage.ClearBuffer(); return; } lblStartupInfo.Visibility = Visibility.Collapsed; // from MagTek Sample Code object dummy = null; string routingNumber = batchPage.micrImage.FindElement( 0, "T", 0, "TT", ref dummy ); string accountNumber = batchPage.micrImage.FindElement( 0, "TT", 0, "A", ref dummy ); string checkNumber = batchPage.micrImage.FindElement( 0, "A", 0, "12", ref dummy ); short trackNumber = 0; var rawMICR = batchPage.micrImage.GetTrack( ref trackNumber ); ScannedDocInfo scannedDoc = null; var rockConfig = RockConfig.Load(); bool scanningMagTekBackImage = false; if ( _currentMagtekScannedDoc != null && _currentMagtekScannedDoc.BackImageData == null && rockConfig.PromptToScanRearImage ) { //// if we didn't get a routingnumber, and we are expecting a back scan, use the scan as the back image //// However, if we got a routing number, assuming we are scanning a new check regardless if ( string.IsNullOrWhiteSpace( routingNumber ) ) { scanningMagTekBackImage = true; } else { scanningMagTekBackImage = false; } } if ( scanningMagTekBackImage ) { scannedDoc = _currentMagtekScannedDoc; } else { scannedDoc = new ScannedDocInfo(); scannedDoc.CurrencyTypeValue = batchPage.SelectedCurrencyValue; scannedDoc.SourceTypeValue = batchPage.SelectedSourceTypeValue; if ( scannedDoc.IsCheck ) { scannedDoc.ScannedCheckMicrData = rawMICR; scannedDoc.RoutingNumber = routingNumber; scannedDoc.AccountNumber = accountNumber; scannedDoc.CheckNumber = checkNumber; WriteToDebugLog( string.Format( "[{0}] - '{1}'", DateTime.Now.ToString( "o" ), scannedDoc.ScannedCheckMicrData ) ); } // set the _currentMagtekScannedDoc in case we are going to scan the back of the image _currentMagtekScannedDoc = scannedDoc; } string imagePath = Path.GetTempPath(); string docImageFileName = Path.Combine( imagePath, string.Format( "scanned_item_{0}.tif", Guid.NewGuid() ) ); if ( File.Exists( docImageFileName ) ) { File.Delete( docImageFileName ); } try { string statusMsg = string.Empty; batchPage.micrImage.TransmitCurrentImage( docImageFileName, ref statusMsg ); if ( !File.Exists( docImageFileName ) ) { throw new Exception( "Unable to retrieve image" ); } if ( scanningMagTekBackImage ) { scannedDoc.BackImageData = File.ReadAllBytes( docImageFileName ); } else { scannedDoc.FrontImageData = File.ReadAllBytes( docImageFileName ); // MagTek puts the symbol '?' for parts of the MICR that it can't read bool gotValidMicr = !string.IsNullOrWhiteSpace( scannedDoc.AccountNumber ) && !scannedDoc.AccountNumber.Contains( '?' ) && !string.IsNullOrWhiteSpace( scannedDoc.RoutingNumber ) && !scannedDoc.RoutingNumber.Contains( '?' ) && !string.IsNullOrWhiteSpace( scannedDoc.CheckNumber ) && !scannedDoc.CheckNumber.Contains( '?' ); if ( scannedDoc.IsCheck && !gotValidMicr ) { scannedDoc.BadMicr = true; } } if ( scannedDoc.BackImageData == null && rockConfig.PromptToScanRearImage ) { // scanning the front image, but still need to scan the back lblScanBackInstructions.Visibility = Visibility.Visible; HideUploadWarningPrompts( true ); DisplayScannedDocInfo( scannedDoc ); } else { // scanned both sides (or just the front if they don't want to scan both sides ) lblScanBackInstructions.Visibility = Visibility.Collapsed; scannedDoc.Upload = !scannedDoc.IsCheck || !( scannedDoc.BadMicr || scannedDoc.Duplicate ); this.ShowScannedDocStatusAndUpload( scannedDoc ); } File.Delete( docImageFileName ); } catch ( Exception ex ) { if ( ex is AggregateException ) { ShowException( ( ex as AggregateException ).Flatten() ); } else { ShowException( ex ); } } finally { batchPage.micrImage.ClearBuffer(); } }
/// <summary> /// Rangers the scanner_ transport item in pocket. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The e.</param> public void rangerScanner_TransportSetItemOutput( object sender, AxRANGERLib._DRangerEvents_TransportSetItemOutputEvent e ) { System.Diagnostics.Debug.WriteLine( string.Format( "{0} : rangerScanner_TransportSetItemOutput", DateTime.Now.ToString( "o" ) ) ); var currentPage = Application.Current.MainWindow.Content; if ( currentPage != this ) { // only accept scans when the scanning page is showing batchPage.micrImage.ClearBuffer(); return; } try { lblStartupInfo.Visibility = Visibility.Collapsed; RockConfig rockConfig = RockConfig.Load(); ScannedDocInfo scannedDoc = new ScannedDocInfo(); // mark it as Upload, but we'll set it to false if anything bad happens before we actually upload scannedDoc.Upload = true; scannedDoc.CurrencyTypeValue = batchPage.SelectedCurrencyValue; scannedDoc.SourceTypeValue = batchPage.SelectedSourceTypeValue; scannedDoc.FrontImageData = GetImageBytesFromRanger( Sides.TransportFront ); if ( rockConfig.EnableRearImage ) { scannedDoc.BackImageData = GetImageBytesFromRanger( Sides.TransportRear ); } if ( scannedDoc.IsCheck ) { string checkMicr = batchPage.rangerScanner.GetMicrText( 1 ); WriteToDebugLog( string.Format( "[{0}] - '{1}'", DateTime.Now.ToString( "o" ), checkMicr ) ); string remainingMicr = checkMicr; string accountNumber = string.Empty; string routingNumber = string.Empty; string checkNumber = string.Empty; // there should always be two transit symbols ('d'). The transit number is between them int transitSymbol1 = remainingMicr.IndexOf( 'd' ); int transitSymbol2 = remainingMicr.LastIndexOf( 'd' ); int transitStart = transitSymbol1 + 1; int transitLength = transitSymbol2 - transitSymbol1 - 1; if ( transitLength > 0 ) { routingNumber = remainingMicr.Substring( transitStart, transitLength ); remainingMicr = remainingMicr.Remove( transitStart - 1, transitLength + 2 ); } // the last 'On-Us' symbol ('c') signifies the end of the account number int lastOnUsPosition = remainingMicr.LastIndexOf( 'c' ); if ( lastOnUsPosition > 0 ) { int accountNumberDigitPosition = lastOnUsPosition - 1; // read all digits to the left of the last 'c' until you run into another 'c' or 'd' while ( accountNumberDigitPosition >= 0 ) { char accountNumberDigit = remainingMicr[accountNumberDigitPosition]; if ( accountNumberDigit == 'c' || accountNumberDigit == 'd' ) { break; } else { accountNumber = accountNumberDigit + accountNumber; accountNumber = accountNumber.Trim(); } accountNumberDigitPosition--; } remainingMicr = remainingMicr.Remove( accountNumberDigitPosition + 1, lastOnUsPosition - accountNumberDigitPosition ); } // any remaining digits that aren't the account number and transit number are probably the check number string[] remainingMicrParts = remainingMicr.Split( new char[] { 'c', ' ' }, StringSplitOptions.RemoveEmptyEntries ); if ( remainingMicrParts.Any() ) { checkNumber = remainingMicrParts.Last(); } scannedDoc.RoutingNumber = routingNumber; scannedDoc.AccountNumber = accountNumber; scannedDoc.CheckNumber = checkNumber; scannedDoc.ScannedCheckMicrData = checkMicr; // look for the "can't read" symbol (or completely blank read ) to detect if the check micr couldn't be read // from http://www.sbulletsupport.com/forum/index.php?topic=172.0 if ( checkMicr.Contains('!') || string.IsNullOrWhiteSpace(checkMicr) ) { scannedDoc.BadMicr = true; scannedDoc.Upload = false; } } ShowScannedDocStatusAndUpload( scannedDoc ); } catch ( Exception ex ) { if ( ex is AggregateException ) { ShowException( ( ex as AggregateException ).Flatten() ); } else { ShowException( ex ); } } }
/// <summary> /// Handles the MicrDataReceived event of the micrImage control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> public void micrImage_MicrDataReceived(object sender, System.EventArgs e) { var currentPage = Application.Current.MainWindow.Content; if (currentPage != this) { // only accept scans when the scanning page is showing batchPage.micrImage.ClearBuffer(); return; } lblStartupInfo.Visibility = Visibility.Collapsed; // from MagTek Sample Code object dummy = null; string routingNumber = batchPage.micrImage.FindElement(0, "T", 0, "TT", ref dummy); string accountNumber = batchPage.micrImage.FindElement(0, "TT", 0, "A", ref dummy); string checkNumber = batchPage.micrImage.FindElement(0, "A", 0, "12", ref dummy); short trackNumber = 0; var rawMICR = batchPage.micrImage.GetTrack(ref trackNumber); ScannedDocInfo scannedDoc = null; var rockConfig = RockConfig.Load(); bool scanningMagTekBackImage = false; if (_currentMagtekScannedDoc != null && _currentMagtekScannedDoc.BackImageData == null && rockConfig.PromptToScanRearImage) { //// if we didn't get a routingnumber, and we are expecting a back scan, use the scan as the back image //// However, if we got a routing number, assuming we are scanning a new check regardless if (string.IsNullOrWhiteSpace(routingNumber)) { scanningMagTekBackImage = true; } else { scanningMagTekBackImage = false; } } if (scanningMagTekBackImage) { scannedDoc = _currentMagtekScannedDoc; } else { scannedDoc = new ScannedDocInfo(); scannedDoc.CurrencyTypeValue = batchPage.SelectedCurrencyValue; scannedDoc.SourceTypeValue = batchPage.SelectedSourceTypeValue; if (scannedDoc.IsCheck) { scannedDoc.ScannedCheckMicrData = rawMICR; scannedDoc.RoutingNumber = routingNumber; scannedDoc.AccountNumber = accountNumber; scannedDoc.CheckNumber = checkNumber; WriteToDebugLog(string.Format("[{0}] - '{1}'", DateTime.Now.ToString("o"), scannedDoc.ScannedCheckMicrData)); } // set the _currentMagtekScannedDoc in case we are going to scan the back of the image _currentMagtekScannedDoc = scannedDoc; } string imagePath = Path.GetTempPath(); string docImageFileName = Path.Combine(imagePath, string.Format("scanned_item_{0}.tif", Guid.NewGuid())); if (File.Exists(docImageFileName)) { File.Delete(docImageFileName); } try { string statusMsg = string.Empty; batchPage.micrImage.TransmitCurrentImage(docImageFileName, ref statusMsg); if (!File.Exists(docImageFileName)) { throw new Exception("Unable to retrieve image"); } if (scanningMagTekBackImage) { scannedDoc.BackImageData = File.ReadAllBytes(docImageFileName); } else { scannedDoc.FrontImageData = File.ReadAllBytes(docImageFileName); // MagTek puts the symbol '?' for parts of the MICR that it can't read bool gotValidMicr = !string.IsNullOrWhiteSpace(scannedDoc.AccountNumber) && !scannedDoc.AccountNumber.Contains('?') && !string.IsNullOrWhiteSpace(scannedDoc.RoutingNumber) && !scannedDoc.RoutingNumber.Contains('?') && !string.IsNullOrWhiteSpace(scannedDoc.CheckNumber) && !scannedDoc.CheckNumber.Contains('?'); if (scannedDoc.IsCheck && !gotValidMicr) { scannedDoc.BadMicr = true; } } if (scannedDoc.BackImageData == null && rockConfig.PromptToScanRearImage) { // scanning the front image, but still need to scan the back lblScanBackInstructions.Visibility = Visibility.Visible; HideUploadWarningPrompts(true); DisplayScannedDocInfo(scannedDoc); } else { // scanned both sides (or just the front if they don't want to scan both sides ) lblScanBackInstructions.Visibility = Visibility.Collapsed; scannedDoc.Upload = !scannedDoc.IsCheck || !(scannedDoc.BadMicr || scannedDoc.Duplicate); this.ShowScannedDocStatusAndUpload(scannedDoc); } File.Delete(docImageFileName); } catch (Exception ex) { if (ex is AggregateException) { ShowException((ex as AggregateException).Flatten()); } else { ShowException(ex); } } finally { batchPage.micrImage.ClearBuffer(); } }
/// <summary> /// Displays the scanned document information. /// </summary> /// <param name="scannedDocInfo">The scanned document information.</param> private void DisplayScannedDocInfo( ScannedDocInfo scannedDocInfo ) { if ( scannedDocInfo.FrontImageData != null ) { BitmapImage bitmapImageFront = new BitmapImage(); bitmapImageFront.BeginInit(); bitmapImageFront.StreamSource = new MemoryStream( scannedDocInfo.FrontImageData ); bitmapImageFront.EndInit(); imgFront.Source = bitmapImageFront; Rock.Wpf.WpfHelper.FadeIn( imgFront, 100 ); lblFront.Visibility = Visibility.Visible; } else { lblFront.Visibility = Visibility.Hidden; imgFront.Source = null; } if ( scannedDocInfo.BackImageData != null ) { BitmapImage bitmapImageBack = new BitmapImage(); bitmapImageBack.BeginInit(); bitmapImageBack.StreamSource = new MemoryStream( scannedDocInfo.BackImageData ); bitmapImageBack.EndInit(); imgBack.Source = bitmapImageBack; Rock.Wpf.WpfHelper.FadeIn( imgBack, 100 ); lblBack.Visibility = Visibility.Visible; colBackImage.Width = new GridLength( 1, GridUnitType.Star ); } else { imgBack.Source = null; lblBack.Visibility = Visibility.Hidden; colBackImage.Width = new GridLength( 0, GridUnitType.Star ); } if ( scannedDocInfo.IsCheck ) { pnlChecks.Visibility = Visibility.Visible; lblRoutingNumber.Content = scannedDocInfo.RoutingNumber ?? "--"; lblAccountNumber.Content = scannedDocInfo.AccountNumber ?? "--"; lblCheckNumber.Content = scannedDocInfo.CheckNumber ?? "--"; lblOtherData.Content = scannedDocInfo.OtherData; spOtherData.Visibility = !string.IsNullOrWhiteSpace( scannedDocInfo.OtherData ) ? Visibility.Visible : Visibility.Collapsed; } else { pnlChecks.Visibility = Visibility.Collapsed; } }
/// <summary> /// Adds the scanned doc to a history of scanned docs, and shows info and status. /// </summary> /// <param name="scannedDocInfo">The scanned check info.</param> public void ShowScannedDocStatus( ScannedDocInfo scannedDocInfo ) { lblExceptions.Visibility = Visibility.Collapsed; CurrentScannedDocInfo = scannedDocInfo; if ( !ScannedDocInfoHistory.Contains( scannedDocInfo ) ) { ScannedDocInfoHistory.Add( scannedDocInfo ); } if ( ScannedDocInfoHistory.Count > 1 ) { gScannedChecksNavigation.Visibility = Visibility.Visible; } else { gScannedChecksNavigation.Visibility = Visibility.Collapsed; } NavigateTo( ScannedDocInfoHistory.Count - 1 ); ExpectingMagTekBackScan = false; var rockConfig = RockConfig.Load(); // If we have the front image and valid routing number, but not the back (and it's a MagTek). Inform them to scan the back; if ( rockConfig.ScannerInterfaceType == RockConfig.InterfaceType.MICRImageRS232 ) { if ( ( imgFront.Source != null ) && ( imgBack.Source == null ) ) { if ( rockConfig.PromptToScanRearImage ) { if ( scannedDocInfo.IsCheck && ( scannedDocInfo.RoutingNumber.Length != 9 || string.IsNullOrWhiteSpace( scannedDocInfo.AccountNumber ) ) ) { ExpectingMagTekBackScan = false; lblScanInstructions.Content = "INFO: Ready to re-scan check"; } else { ExpectingMagTekBackScan = true; lblScanInstructions.Content = string.Format( "INFO: Insert the {0} again facing the other direction to get an image of the back.", scannedDocInfo.IsCheck ? "check" : "item" ); } } } else { UpdateScanInstructions(); } } }
/// <summary> /// Shows the upload warnings. /// </summary> private void ShowUploadWarnings( ScannedDocInfo scannedDocInfo ) { var rockConfig = RockConfig.Load(); ConfirmUploadBadScannedDoc = scannedDocInfo; lblScanCheckWarningDuplicate.Visibility = scannedDocInfo.Duplicate ? Visibility.Visible : Visibility.Collapsed; lblScanCheckWarningBadMicr.Visibility = scannedDocInfo.BadMicr ? Visibility.Visible : Visibility.Collapsed; lblScanItemUploadSuccess.Visibility = Visibility.Collapsed; pnlPromptForUpload.Visibility = scannedDocInfo.Duplicate || scannedDocInfo.BadMicr ? Visibility.Visible : Visibility.Collapsed; btnStart.IsEnabled = false; btnStopScanning.IsEnabled = true; }
/// <summary> /// Displays the scanned document information. /// </summary> /// <param name="scannedDocInfo">The scanned document information.</param> private void DisplayScannedDocInfo(ScannedDocInfo scannedDocInfo) { if (scannedDocInfo.FrontImageData != null) { BitmapImage bitmapImageFront = new BitmapImage(); bitmapImageFront.BeginInit(); bitmapImageFront.StreamSource = new MemoryStream(scannedDocInfo.FrontImageData); bitmapImageFront.EndInit(); imgFront.Source = bitmapImageFront; } else { imgFront.Source = null; } if (scannedDocInfo.BackImageData != null) { BitmapImage bitmapImageBack = new BitmapImage(); bitmapImageBack.BeginInit(); bitmapImageBack.StreamSource = new MemoryStream(scannedDocInfo.BackImageData); bitmapImageBack.EndInit(); imgBack.Source = bitmapImageBack; } else { imgBack.Source = null; } if (scannedDocInfo.IsCheck) { pnlChecks.Visibility = Visibility.Visible; lblRoutingNumber.Content = scannedDocInfo.RoutingNumber ?? "--"; lblAccountNumber.Content = scannedDocInfo.AccountNumber ?? "--"; lblCheckNumber.Content = scannedDocInfo.CheckNumber ?? "--"; } else { pnlChecks.Visibility = Visibility.Collapsed; } if (scannedDocInfo.BadMicr) { if (string.IsNullOrWhiteSpace(scannedDocInfo.AccountNumber)) { lblScanCheckWarningBadMicr.Content = "WARNING: Check account information not found. Try scanning again with the check facing the other direction."; } else { lblScanCheckWarningBadMicr.Content = "WARNING: Check account information is invalid. Try scanning again."; } lblScanCheckWarningBadMicr.Visibility = Visibility.Visible; } else { lblScanCheckWarningBadMicr.Visibility = Visibility.Collapsed; } if (scannedDocInfo.Duplicate) { lblScanCheckWarningDuplicate.Visibility = Visibility.Visible; } else { lblScanCheckWarningDuplicate.Visibility = Visibility.Collapsed; } btnDeleteItem.Visibility = Visibility.Visible; if (ScannedDocInfoHistory.Any(a => a.IsCheck && (a.BadMicr || a.Duplicate))) { lblSomeBadScans.Visibility = Visibility.Visible; lblScanInstructions.Visibility = Visibility.Collapsed; } else { lblSomeBadScans.Visibility = Visibility.Collapsed; lblScanInstructions.Visibility = Visibility.Visible; } }
/// <summary> /// Uploads the scanned item. /// </summary> /// <param name="scannedDocInfo">The scanned document information.</param> public static void UploadScannedItem(ScannedDocInfo scannedDocInfo) { RockRestClient client = EnsureUploadScanRestClient(); // upload image of front of doc (if was successfully scanned) int?frontImageBinaryFileId = null; if (scannedDocInfo.FrontImageData != null) { string frontImageFileName = string.Format("image1_{0}.png", DateTime.Now.ToString("o").RemoveSpecialCharacters()); frontImageBinaryFileId = client.UploadBinaryFile(frontImageFileName, Rock.Client.SystemGuid.BinaryFiletype.CONTRIBUTION_IMAGE.AsGuid(), scannedDocInfo.FrontImagePngBytes, false); } // upload image of back of doc (if it exists) int?backImageBinaryFileId = null; if (scannedDocInfo.BackImageData != null) { // upload image of back of doc string backImageFileName = string.Format("image2_{0}.png", DateTime.Now.ToString("o").RemoveSpecialCharacters()); backImageBinaryFileId = client.UploadBinaryFile(backImageFileName, Rock.Client.SystemGuid.BinaryFiletype.CONTRIBUTION_IMAGE.AsGuid(), scannedDocInfo.BackImagePngBytes, false); } FinancialPaymentDetail financialPaymentDetail = new FinancialPaymentDetail(); financialPaymentDetail.CurrencyTypeValueId = scannedDocInfo.CurrencyTypeValue.Id; financialPaymentDetail.Guid = Guid.NewGuid(); var financialPaymentDetailId = client.PostData <FinancialPaymentDetail>("api/FinancialPaymentDetails", financialPaymentDetail).AsIntegerOrNull(); FinancialTransaction financialTransaction = new FinancialTransaction(); financialTransaction.BatchId = batchPage.SelectedFinancialBatch.Id; financialTransaction.TransactionCode = string.Empty; financialTransaction.Summary = string.Empty; financialTransaction.Guid = Guid.NewGuid(); financialTransaction.TransactionDateTime = batchPage.SelectedFinancialBatch.BatchStartDateTime; financialTransaction.FinancialPaymentDetailId = financialPaymentDetailId; financialTransaction.SourceTypeValueId = scannedDocInfo.SourceTypeValue.Id; financialTransaction.TransactionTypeValueId = transactionTypeValueContribution.Id; var accounts = scannedDocInfo.AccountAmountCaptureList; if (accounts != null) { var accountsWithValues = accounts.Where(a => a.Amount > 0).ToList(); if (accountsWithValues != null && accountsWithValues.Count() > 0) { AddFinancialTransactionDetailForEachAccount(accountsWithValues, financialTransaction); } } int?uploadedTransactionId; if (scannedDocInfo.IsCheck) { financialTransaction.TransactionCode = scannedDocInfo.CheckNumber; financialTransaction.MICRStatus = scannedDocInfo.BadMicr ? MICRStatus.Fail : MICRStatus.Success; FinancialTransactionScannedCheck financialTransactionScannedCheck = new FinancialTransactionScannedCheck(); // Rock server will encrypt CheckMicrPlainText to this since we can't have the DataEncryptionKey in a RestClient financialTransactionScannedCheck.FinancialTransaction = financialTransaction; financialTransactionScannedCheck.ScannedCheckMicrData = scannedDocInfo.ScannedCheckMicrData; financialTransactionScannedCheck.ScannedCheckMicrParts = scannedDocInfo.ScannedCheckMicrParts; uploadedTransactionId = client.PostData <FinancialTransactionScannedCheck>("api/FinancialTransactions/PostScanned", financialTransactionScannedCheck).AsIntegerOrNull(); } else { //FinancialTransactionDetail uploadedTransactionId = client.PostData <FinancialTransaction>("api/FinancialTransactions", financialTransaction as FinancialTransaction).AsIntegerOrNull(); } // upload FinancialTransactionImage records for front/back if (frontImageBinaryFileId.HasValue) { FinancialTransactionImage financialTransactionImageFront = new FinancialTransactionImage(); financialTransactionImageFront.BinaryFileId = frontImageBinaryFileId.Value; financialTransactionImageFront.TransactionId = uploadedTransactionId.Value; financialTransactionImageFront.Order = 0; financialTransactionImageFront.Guid = Guid.NewGuid(); client.PostData <FinancialTransactionImage>("api/FinancialTransactionImages", financialTransactionImageFront); } if (backImageBinaryFileId.HasValue) { FinancialTransactionImage financialTransactionImageBack = new FinancialTransactionImage(); financialTransactionImageBack.BinaryFileId = backImageBinaryFileId.Value; financialTransactionImageBack.TransactionId = uploadedTransactionId.Value; financialTransactionImageBack.Order = 1; financialTransactionImageBack.Guid = Guid.NewGuid(); client.PostData <FinancialTransactionImage>("api/FinancialTransactionImages", financialTransactionImageBack); } scannedDocInfo.TransactionId = uploadedTransactionId; financialTransaction.Id = uploadedTransactionId ?? 0; financialTransaction.CreatedDateTime = financialTransaction.CreatedDateTime ?? DateTime.Now; batchPage.SelectedFinancialBatch.Transactions.Add(financialTransaction); var transactionList = batchPage.grdBatchItems.DataContext as BindingList <FinancialTransaction>; transactionList.Insert(0, financialTransaction); ItemsUploaded++; }
/// <summary> /// Handles the MicrDataReceived event of the micrImage control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> private void micrImage_MicrDataReceived( object sender, System.EventArgs e ) { var currentPage = Application.Current.MainWindow.Content; if ( currentPage != this.ScanningPage ) { // only accept scans when the scanning page is showing micrImage.ClearBuffer(); return; } // from MagTek Sample Code object dummy = null; string routingNumber = micrImage.FindElement( 0, "T", 0, "TT", ref dummy ); string accountNumber = micrImage.FindElement( 0, "TT", 0, "A", ref dummy ); string checkNumber = micrImage.FindElement( 0, "A", 0, "12", ref dummy ); ScannedDocInfo scannedDoc = null; var rockConfig = RockConfig.Load(); bool scanningMagTekBackImage = false; if ( ScanningPage.ExpectingMagTekBackScan ) { //// if we didn't get a routingnumber, and we are expecting a back scan, use the scan as the back image //// However, if we got a routing number, assuming we are scanning a new check regardless if ( string.IsNullOrWhiteSpace( routingNumber ) ) { scanningMagTekBackImage = true; } else { scanningMagTekBackImage = false; } } if ( scanningMagTekBackImage ) { scannedDoc = ScannedDocList.Last(); } else { scannedDoc = new ScannedDocInfo(); scannedDoc.CurrencyTypeValue = this.SelectedCurrencyValue; scannedDoc.SourceTypeValue = this.SelectedSourceTypeValue; if ( scannedDoc.IsCheck ) { scannedDoc.RoutingNumber = routingNumber; scannedDoc.AccountNumber = accountNumber; scannedDoc.CheckNumber = checkNumber; } } string imagePath = Path.GetTempPath(); string docImageFileName = Path.Combine( imagePath, string.Format( "scanned_item_{0}.tif", Guid.NewGuid() ) ); if ( File.Exists( docImageFileName ) ) { File.Delete( docImageFileName ); } try { string statusMsg = string.Empty; micrImage.TransmitCurrentImage( docImageFileName, ref statusMsg ); if ( !File.Exists( docImageFileName ) ) { throw new Exception( "Unable to retrieve image" ); } else { if ( scanningMagTekBackImage ) { scannedDoc.BackImageData = File.ReadAllBytes( docImageFileName ); } else { scannedDoc.FrontImageData = File.ReadAllBytes( docImageFileName ); // MagTek puts the symbol '?' for parts of the MICR that it can't read bool gotValidMicr = !string.IsNullOrWhiteSpace( scannedDoc.AccountNumber ) && !scannedDoc.AccountNumber.Contains( '?' ) && !string.IsNullOrWhiteSpace( scannedDoc.RoutingNumber ) && !scannedDoc.RoutingNumber.Contains( '?' ) && !string.IsNullOrWhiteSpace( scannedDoc.CheckNumber ) && !scannedDoc.CheckNumber.Contains( '?' ); if ( scannedDoc.IsCheck && !gotValidMicr ) { scannedDoc.BadMicr = true; } else { if ( IsDuplicateScan( scannedDoc ) ) { scannedDoc.Duplicate = true; } else { ScannedDocList.Enqueue( scannedDoc ); } } } ScanningPage.ShowScannedDocStatus( scannedDoc ); File.Delete( docImageFileName ); } } catch ( Exception ex ) { if ( ex is AggregateException ) { ScanningPage.ShowException( ( ex as AggregateException ).Flatten() ); } else { ScanningPage.ShowException( ex ); } } finally { micrImage.ClearBuffer(); } }
/// <summary> /// Rangers the scanner_ transport item in pocket. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The e.</param> private void rangerScanner_TransportSetItemOutput( object sender, AxRANGERLib._DRangerEvents_TransportSetItemOutputEvent e ) { try { RockConfig rockConfig = RockConfig.Load(); ScannedDocInfo scannedDoc = new ScannedDocInfo(); scannedDoc.CurrencyTypeValue = this.SelectedCurrencyValue; scannedDoc.SourceTypeValue = this.SelectedSourceTypeValue; scannedDoc.FrontImageData = GetImageBytesFromRanger( Sides.TransportFront ); if ( rockConfig.EnableRearImage ) { scannedDoc.BackImageData = GetImageBytesFromRanger( Sides.TransportRear ); } if ( scannedDoc.IsCheck ) { string checkMicr = rangerScanner.GetMicrText( 1 ).Trim(); string remainingMicr = checkMicr; string accountNumber = string.Empty; string routingNumber = string.Empty; string checkNumber = string.Empty; // there should always be two transit symbols ('d'). The transit number is between them int transitSymbol1 = remainingMicr.IndexOf( 'd' ); int transitSymbol2 = remainingMicr.LastIndexOf( 'd' ); int transitStart = transitSymbol1 + 1; int transitLength = transitSymbol2 - transitSymbol1 - 1; if ( transitLength > 0 ) { routingNumber = remainingMicr.Substring( transitStart, transitLength ); remainingMicr = remainingMicr.Remove( transitStart - 1, transitLength + 2 ); } // the last 'On-Us' symbol ('c') signifys the end of the account number int lastOnUsPosition = remainingMicr.LastIndexOf( 'c' ); if ( lastOnUsPosition > 0 ) { int accountNumberDigitPosition = lastOnUsPosition - 1; // read all digits to the left of the last 'c' until you run into a non-numeric (except for '!' whichs means invalid) while ( accountNumberDigitPosition >= 0 ) { char accountNumberDigit = remainingMicr[accountNumberDigitPosition]; if ( char.IsNumber( accountNumberDigit ) || accountNumberDigit.Equals( '!' ) ) { accountNumber = accountNumberDigit + accountNumber; } else { break; } accountNumberDigitPosition--; } remainingMicr = remainingMicr.Remove( accountNumberDigitPosition + 1, lastOnUsPosition - accountNumberDigitPosition ); } // any remaining digits that aren't the account number and transit number are probably the check number string[] remainingMicrParts = remainingMicr.Split( new char[] { 'c', ' ' }, StringSplitOptions.RemoveEmptyEntries ); if ( remainingMicrParts.Length == 1 ) { checkNumber = remainingMicrParts[0]; } scannedDoc.RoutingNumber = routingNumber; scannedDoc.AccountNumber = accountNumber; scannedDoc.CheckNumber = checkNumber; if ( routingNumber.Length != 9 || string.IsNullOrEmpty( accountNumber ) || checkMicr.Contains('!') || string.IsNullOrEmpty(checkNumber) ) { scannedDoc.BadMicr = true; rangerScanner.StopFeeding(); } else { if ( IsDuplicateScan( scannedDoc ) ) { scannedDoc.Duplicate = true; rangerScanner.StopFeeding(); rangerScanner.ClearTrack(); } else { ScannedDocList.Enqueue( scannedDoc ); } } } else { ScannedDocList.Enqueue( scannedDoc ); } ScanningPage.ShowScannedDocStatus( scannedDoc ); } catch ( Exception ex ) { if ( ex is AggregateException ) { ScanningPage.ShowException( ( ex as AggregateException ).Flatten() ); } else { ScanningPage.ShowException( ex ); } } }
/// <summary> /// Determines whether [is duplicate scan] [the specified scanned document]. /// </summary> /// <param name="scannedDoc">The scanned document.</param> /// <returns></returns> private bool IsDuplicateScan( ScannedDocInfo scannedDoc ) { if ( !scannedDoc.IsCheck ) { return false; } if ( checkforDuplicateClient == null ) { var rockConfig = RockConfig.Load(); checkforDuplicateClient = new RockRestClient( rockConfig.RockBaseUrl ); checkforDuplicateClient.Login( rockConfig.Username, rockConfig.Password ); } // first check if we have already scanned this doc during this session (we might not have uploaded it yet) var alreadyScanned = ScannedDocList.Any( a => a.IsCheck && a.ScannedCheckMicr == scannedDoc.ScannedCheckMicr ); // if we didn't already scan it in this session, check the server if ( !alreadyScanned ) { alreadyScanned = checkforDuplicateClient.PostDataWithResult<string, bool>( "api/FinancialTransactions/AlreadyScanned", scannedDoc.ScannedCheckMicr ); } return alreadyScanned; }
/// <summary> /// Determines whether [is duplicate scan] [the specified scanned document]. /// </summary> /// <param name="scannedDoc">The scanned document.</param> /// <returns></returns> private bool IsDuplicateScan( ScannedDocInfo scannedDoc ) { if ( !scannedDoc.IsCheck ) { return false; } if ( scannedDoc.BadMicr ) { return false; } var uploadClient = EnsureUploadScanRestClient(); if ( uploadClient == null ) { var rockConfig = RockConfig.Load(); uploadClient = new RockRestClient( rockConfig.RockBaseUrl ); uploadClient.Login( rockConfig.Username, rockConfig.Password ); } var alreadyScanned = uploadClient.PostDataWithResult<string, bool>( "api/FinancialTransactions/AlreadyScanned", scannedDoc.ScannedCheckMicrData ); return alreadyScanned; }
/// <summary> /// Displays the scanned document information. /// </summary> /// <param name="scannedDocInfo">The scanned document information.</param> private void DisplayScannedDocInfo( ScannedDocInfo scannedDocInfo ) { if ( scannedDocInfo.FrontImageData != null ) { BitmapImage bitmapImageFront = new BitmapImage(); bitmapImageFront.BeginInit(); bitmapImageFront.StreamSource = new MemoryStream( scannedDocInfo.FrontImageData ); bitmapImageFront.EndInit(); imgFront.Source = bitmapImageFront; } else { imgFront.Source = null; } if ( scannedDocInfo.BackImageData != null ) { BitmapImage bitmapImageBack = new BitmapImage(); bitmapImageBack.BeginInit(); bitmapImageBack.StreamSource = new MemoryStream( scannedDocInfo.BackImageData ); bitmapImageBack.EndInit(); imgBack.Source = bitmapImageBack; } else { imgBack.Source = null; } if ( scannedDocInfo.IsCheck ) { pnlChecks.Visibility = Visibility.Visible; lblRoutingNumber.Content = scannedDocInfo.RoutingNumber ?? "--"; lblAccountNumber.Content = scannedDocInfo.AccountNumber ?? "--"; lblCheckNumber.Content = scannedDocInfo.CheckNumber ?? "--"; } else { pnlChecks.Visibility = Visibility.Collapsed; } if ( scannedDocInfo.BadMicr ) { if ( string.IsNullOrWhiteSpace( scannedDocInfo.AccountNumber ) ) { lblScanCheckWarningBadMicr.Content = "WARNING: Check account information not found. Try scanning again with the check facing the other direction."; } else { lblScanCheckWarningBadMicr.Content = "WARNING: Check account information is invalid. Try scanning again."; } lblScanCheckWarningBadMicr.Visibility = Visibility.Visible; } else { lblScanCheckWarningBadMicr.Visibility = Visibility.Collapsed; } if ( scannedDocInfo.Duplicate ) { lblScanCheckWarningDuplicate.Visibility = Visibility.Visible; } else { lblScanCheckWarningDuplicate.Visibility = Visibility.Collapsed; } btnDeleteItem.Visibility = Visibility.Visible; if ( ScannedDocInfoHistory.Any( a => a.IsCheck && ( a.BadMicr || a.Duplicate ) ) ) { lblSomeBadScans.Visibility = Visibility.Visible; lblScanInstructions.Visibility = Visibility.Collapsed; } else { lblSomeBadScans.Visibility = Visibility.Collapsed; lblScanInstructions.Visibility = Visibility.Visible; } }
/// <summary> /// Shows the startup page. /// </summary> private void ShowStartupPage() { var rockConfig = RockConfig.Load(); HideUploadWarningPrompts(); lblExceptions.Visibility = Visibility.Collapsed; lblStartupInfo.Visibility = Visibility.Visible; lblNoItemsFound.Visibility = Visibility.Collapsed; lblScannerNotReady.Visibility = Visibility.Collapsed; ScannedDocInfo sampleDocInfo = new ScannedDocInfo(); sampleDocInfo.CurrencyTypeValue = batchPage.CurrencyValueList.FirstOrDefault( a => a.Guid == RockConfig.Load().SourceTypeValueGuid.AsGuid() ); DisplayScannedDocInfo( sampleDocInfo ); bool scanningChecks = RockConfig.Load().TenderTypeValueGuid.AsGuid() == Rock.Client.SystemGuid.DefinedValue.CURRENCY_TYPE_CHECK.AsGuid(); lblNoItemsFound.Content = string.Format( "No {0} detected in scanner. Make sure {0} are properly in the feed tray.", scanningChecks ? "checks" : "items" ); lblScanBackInstructions.Content = string.Format( "Insert the {0} again facing the other direction to get an image of the back.", scanningChecks ? "check" : "item" ); lblScanBackInstructions.Visibility = Visibility.Collapsed; if ( RockConfig.Load().ScannerInterfaceType == RockConfig.InterfaceType.MICRImageRS232 ) { lblStartupInfo.Content = string.Format( "Ready to scan next {0}.", scanningChecks ? "check" : "item" ); // no need for a stop/start button when in MagTek mode btnStart.Visibility = Visibility.Hidden; btnStopScanning.Visibility = Visibility.Hidden; } else { btnStart.Visibility = Visibility.Visible; btnStopScanning.Visibility = Visibility.Visible; lblStartupInfo.Content = "Click Start to begin"; } }
/// <summary> /// Shows the startup page. /// </summary> private void ShowStartupPage() { var rockConfig = RockConfig.Load(); lblExceptions.Visibility = Visibility.Collapsed; lblScanCheckWarningBadMicr.Visibility = Visibility.Collapsed; lblScanCheckWarningDuplicate.Visibility = Visibility.Collapsed; if ( rockConfig.ScannerInterfaceType == RockConfig.InterfaceType.RangerApi && rockConfig.EnableRearImage ) { lblBack.Visibility = Visibility.Visible; } else if ( rockConfig.ScannerInterfaceType == RockConfig.InterfaceType.MICRImageRS232 && rockConfig.PromptToScanRearImage ) { lblBack.Visibility = Visibility.Visible; } else { lblBack.Visibility = Visibility.Hidden; } this.ClearScannedDocHistory(); lblSomeBadScans.Visibility = Visibility.Collapsed; ExpectingMagTekBackScan = false; ScannedDocInfo sampleDocInfo = new ScannedDocInfo(); sampleDocInfo.CurrencyTypeValue = batchPage.CurrencyValueList.FirstOrDefault( a => a.Guid == RockConfig.Load().SourceTypeValueGuid.AsGuid() ); DisplayScannedDocInfo( sampleDocInfo ); gScannedChecksNavigation.Visibility = Visibility.Collapsed; btnDeleteItem.Visibility = Visibility.Collapsed; UpdateScanInstructions(); }
/// <summary> /// Uploads the scanned item. /// </summary> /// <param name="scannedDocInfo">The scanned document information.</param> private void UploadScannedItem( ScannedDocInfo scannedDocInfo ) { RockRestClient client = EnsureUploadScanRestClient(); // upload image of front of doc string frontImageFileName = string.Format( "image1_{0}.png", DateTime.Now.ToString( "o" ).RemoveSpecialCharacters() ); int frontImageBinaryFileId = client.UploadBinaryFile( frontImageFileName, Rock.Client.SystemGuid.BinaryFiletype.CONTRIBUTION_IMAGE.AsGuid(), scannedDocInfo.FrontImagePngBytes, false ); // upload image of back of doc (if it exists) int? backImageBinaryFileId = null; if ( scannedDocInfo.BackImageData != null ) { // upload image of back of doc string backImageFileName = string.Format( "image2_{0}.png", DateTime.Now.ToString( "o" ).RemoveSpecialCharacters() ); backImageBinaryFileId = client.UploadBinaryFile( backImageFileName, Rock.Client.SystemGuid.BinaryFiletype.CONTRIBUTION_IMAGE.AsGuid(), scannedDocInfo.BackImagePngBytes, false ); } FinancialPaymentDetail financialPaymentDetail = new FinancialPaymentDetail(); financialPaymentDetail.CurrencyTypeValueId = scannedDocInfo.CurrencyTypeValue.Id; financialPaymentDetail.Guid = Guid.NewGuid(); var financialPaymentDetailId = client.PostData<FinancialPaymentDetail>( "api/FinancialPaymentDetails", financialPaymentDetail ).AsIntegerOrNull(); FinancialTransaction financialTransaction = new FinancialTransaction(); financialTransaction.BatchId = batchPage.SelectedFinancialBatch.Id; financialTransaction.TransactionCode = string.Empty; financialTransaction.Summary = string.Empty; financialTransaction.Guid = Guid.NewGuid(); financialTransaction.TransactionDateTime = batchPage.SelectedFinancialBatch.BatchStartDateTime; financialTransaction.FinancialPaymentDetailId = financialPaymentDetailId; financialTransaction.SourceTypeValueId = scannedDocInfo.SourceTypeValue.Id; financialTransaction.TransactionTypeValueId = transactionTypeValueContribution.Id; int? uploadedTransactionId; if ( scannedDocInfo.IsCheck ) { financialTransaction.TransactionCode = scannedDocInfo.CheckNumber; financialTransaction.MICRStatus = scannedDocInfo.BadMicr ? MICRStatus.Fail : MICRStatus.Success; FinancialTransactionScannedCheck financialTransactionScannedCheck = new FinancialTransactionScannedCheck(); // Rock server will encrypt CheckMicrPlainText to this since we can't have the DataEncryptionKey in a RestClient financialTransactionScannedCheck.FinancialTransaction = financialTransaction; financialTransactionScannedCheck.ScannedCheckMicrData = scannedDocInfo.ScannedCheckMicrData; financialTransactionScannedCheck.ScannedCheckMicrParts = scannedDocInfo.ScannedCheckMicrParts; uploadedTransactionId = client.PostData<FinancialTransactionScannedCheck>( "api/FinancialTransactions/PostScanned", financialTransactionScannedCheck ).AsIntegerOrNull(); } else { uploadedTransactionId = client.PostData<FinancialTransaction>( "api/FinancialTransactions", financialTransaction as FinancialTransaction ).AsIntegerOrNull(); } // upload FinancialTransactionImage records for front/back FinancialTransactionImage financialTransactionImageFront = new FinancialTransactionImage(); financialTransactionImageFront.BinaryFileId = frontImageBinaryFileId; financialTransactionImageFront.TransactionId = uploadedTransactionId.Value; financialTransactionImageFront.Order = 0; financialTransactionImageFront.Guid = Guid.NewGuid(); client.PostData<FinancialTransactionImage>( "api/FinancialTransactionImages", financialTransactionImageFront ); if ( backImageBinaryFileId.HasValue ) { FinancialTransactionImage financialTransactionImageBack = new FinancialTransactionImage(); financialTransactionImageBack.BinaryFileId = backImageBinaryFileId.Value; financialTransactionImageBack.TransactionId = uploadedTransactionId.Value; financialTransactionImageBack.Order = 1; financialTransactionImageBack.Guid = Guid.NewGuid(); client.PostData<FinancialTransactionImage>( "api/FinancialTransactionImages", financialTransactionImageBack ); } scannedDocInfo.TransactionId = uploadedTransactionId; financialTransaction.Id = uploadedTransactionId ?? 0; financialTransaction.CreatedDateTime = financialTransaction.CreatedDateTime ?? DateTime.Now; var transactionList = batchPage.grdBatchItems.DataContext as BindingList<FinancialTransaction>; transactionList.Insert( 0, financialTransaction ); _itemsUploaded++; ShowUploadStats(); ShowUploadSuccess(); }
/// <summary> /// Rangers the scanner_ transport item in pocket. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The e.</param> public void rangerScanner_TransportSetItemOutput(object sender, AxRANGERLib._DRangerEvents_TransportSetItemOutputEvent e) { System.Diagnostics.Debug.WriteLine(string.Format("{0} : rangerScanner_TransportSetItemOutput", DateTime.Now.ToString("o"))); var currentPage = Application.Current.MainWindow.Content; if (currentPage != this) { // only accept scans when the scanning page is showing batchPage.micrImage.ClearBuffer(); return; } try { lblStartupInfo.Visibility = Visibility.Collapsed; RockConfig rockConfig = RockConfig.Load(); ScannedDocInfo scannedDoc = new ScannedDocInfo(); // mark it as Upload, but we'll set it to false if anything bad happens before we actually upload scannedDoc.Upload = true; scannedDoc.CurrencyTypeValue = batchPage.SelectedCurrencyValue; scannedDoc.SourceTypeValue = batchPage.SelectedSourceTypeValue; scannedDoc.FrontImageData = GetImageBytesFromRanger(RangerSides.TransportFront); if (rockConfig.EnableRearImage) { scannedDoc.BackImageData = GetImageBytesFromRanger(RangerSides.TransportRear); } if (scannedDoc.IsCheck) { string checkMicr = batchPage.rangerScanner.GetMicrText(1); WriteToDebugLog(string.Format("[{0}] - '{1}'", DateTime.Now.ToString("o"), checkMicr)); string remainingMicr = checkMicr; string accountNumber = string.Empty; string routingNumber = string.Empty; string checkNumber = string.Empty; // there should always be two transit symbols ('d'). The transit number is between them int transitSymbol1 = remainingMicr.IndexOf((char)RangerE13BMicrSymbols.E13B_TransitSymbol); int transitSymbol2 = remainingMicr.LastIndexOf((char)RangerE13BMicrSymbols.E13B_TransitSymbol); int transitStart = transitSymbol1 + 1; int transitLength = transitSymbol2 - transitSymbol1 - 1; if (transitLength > 0) { routingNumber = remainingMicr.Substring(transitStart, transitLength); remainingMicr = remainingMicr.Remove(transitStart - 1, transitLength + 2); } char[] separatorSymbols = new char[] { (char)RangerE13BMicrSymbols.E13B_TransitSymbol, (char)RangerE13BMicrSymbols.E13B_OnUsSymbol, (char)RangerE13BMicrSymbols.E13B_AmountSymbol }; // the last 'On-Us' symbol ('c') signifies the end of the account number int lastOnUsPosition = remainingMicr.LastIndexOf((char)RangerE13BMicrSymbols.E13B_OnUsSymbol); if (lastOnUsPosition > 0) { int accountNumberDigitPosition = lastOnUsPosition - 1; // read all digits to the left of the last 'OnUs' until you run into another seperator symbol while (accountNumberDigitPosition >= 0) { char accountNumberDigit = remainingMicr[accountNumberDigitPosition]; if (separatorSymbols.Contains(accountNumberDigit)) { break; } else { accountNumber = accountNumberDigit + accountNumber; accountNumber = accountNumber.Trim(); } accountNumberDigitPosition--; } remainingMicr = remainingMicr.Remove(accountNumberDigitPosition + 1, lastOnUsPosition - accountNumberDigitPosition); } // any remaining digits that aren't the account number and transit number are probably the check number string[] remainingMicrParts = remainingMicr.Split(new char[] { (char)RangerE13BMicrSymbols.E13B_OnUsSymbol, ' ' }, StringSplitOptions.RemoveEmptyEntries); string otherData = null; if (remainingMicrParts.Any()) { checkNumber = remainingMicrParts.Last(); // throw any remaining data into 'otherData' (a reject symbol could be in the other data) remainingMicr = remainingMicr.Replace((char)RangerE13BMicrSymbols.E13B_OnUsSymbol, ' '); remainingMicr = remainingMicr.Replace(checkNumber, string.Empty); otherData = remainingMicr; } scannedDoc.RoutingNumber = routingNumber; scannedDoc.AccountNumber = accountNumber; scannedDoc.CheckNumber = checkNumber; scannedDoc.OtherData = otherData; scannedDoc.ScannedCheckMicrData = checkMicr; // look for the "can't read" symbol (or completely blank read ) to detect if the check micr couldn't be read // from http://www.sbulletsupport.com/forum/index.php?topic=172.0 if (checkMicr.Contains((char)RangerCommonSymbols.RangerRejectSymbol) || string.IsNullOrWhiteSpace(checkMicr)) { scannedDoc.BadMicr = true; scannedDoc.Upload = false; } } ShowScannedDocStatusAndUpload(scannedDoc); } catch (Exception ex) { if (ex is AggregateException) { ShowException((ex as AggregateException).Flatten()); } else { ShowException(ex); } } }