Esempio n. 1
0
        public override void ExecuteJob()
        {
            Log.Information("Scanning database for completed generate corresponding voucher");

            using (var dbConnection = new SqlConnection(Configuration.SqlConnectionString))
            {
                using (var dbContext = new DipsDbContext(dbConnection))
                {
                    //Get all the potential batches that have been completed
                    var completedBatches =
                        dbContext.Queues
                        .Where(q =>
                               !q.ResponseCompleted &&
                               q.S_LOCATION == DipsLocationType.GenerateCorrespondingVoucherDone.Value &&
                               q.S_LOCK.Trim() == "0")
                        .ToList();

                    Log.Information("Found {0} completed generate corresponding voucher", completedBatches.Count());

                    foreach (var completedBatch in completedBatches)
                    {
                        Log.Debug("Creating response for batch {@batch}", completedBatch.S_BATCH);

                        //only commit the transaction if
                        // a) we were the first application to mark this batch row as CorrectCodelineCompleted (DipsQueue uses optimistic concurrency)
                        // b) we were able to place a response message on the bus
                        using (var tx = dbContext.BeginTransaction())
                        {
                            try
                            {
                                //mark the line as completed
                                completedBatch.ResponseCompleted = true;
                                var routingKey = completedBatch.RoutingKey;

                                dbContext.SaveChanges();

                                var batchNumber = completedBatch.S_BATCH;

                                //get the vouchers, generate and send the response
                                var originalVouchers = dbContext.NabChqPods
                                                       .Where(
                                    v =>
                                    v.S_BATCH == batchNumber && v.S_DEL_IND != "  255" &&
                                    v.isGeneratedVoucher != "1" &&
                                    (v.export_exclude_flag.Trim() != "1"))
                                                       .ToList();

                                var generatedVouchers = dbContext.NabChqPods
                                                        .Where(
                                    v =>
                                    v.S_BATCH == batchNumber && v.S_DEL_IND != "  255" &&
                                    v.isGeneratedVoucher == "1" &&
                                    (v.export_exclude_flag.Trim() != "1"))
                                                        .ToList();

                                var batchResponse = new GenerateCorrespondingVoucherResponse
                                {
                                    updateVoucher = originalVouchers.Select(v => new VoucherInformation()
                                    {
                                        voucherBatch = new VoucherBatch
                                        {
                                            batchAccountNumber = v.batchAccountNumber,
                                            batchType          = ResponseHelper.TrimString(v.batch_type),
                                            captureBsb         = v.captureBSB,
                                            collectingBank     = v.collecting_bank,
                                            processingState    =
                                                ResponseHelper.ParseState(ResponseHelper.TrimString(v.processing_state)),
                                            scannedBatchNumber = completedBatch.S_BATCH,
                                            unitID             = originalVouchers.First().unit_id,
                                            workType           =
                                                ResponseHelper.ParseWorkType(
                                                    ResponseHelper.TrimString(completedBatch.S_JOB_ID)),
                                            subBatchType = ResponseHelper.TrimString(v.sub_batch_type),
                                        },

                                        voucherProcess = new VoucherProcess
                                        {
                                            adjustedFlag        = ResponseHelper.ParseStringAsBool(v.adjustedFlag),
                                            highValueFlag       = ResponseHelper.ParseStringAsBool(v.highValueFlag),
                                            isGeneratedVoucher  = ResponseHelper.ParseStringAsBool(v.isGeneratedVoucher),
                                            manualRepair        = ResponseHelper.ParseStringAsInt(v.man_rep_ind),
                                            preAdjustmentAmount = ResponseHelper.ParseAmountField(v.orig_amount),
                                            presentationMode    = ResponseHelper.TrimString(v.presentationMode),
                                            rawMICR             = ResponseHelper.TrimString(v.raw_micr),
                                            rawOCR                   = ResponseHelper.TrimString(v.raw_ocr),
                                            repostFromDRN            = ResponseHelper.TrimString(v.repostFromDRN),
                                            repostFromProcessingDate =
                                                ResponseHelper.ParseDateField(v.repostFromProcessingDate),
                                            surplusItemFlag                  = ResponseHelper.ParseStringAsBool(v.surplusItemFlag),
                                            suspectFraud                     = ResponseHelper.ParseStringAsBool(v.micr_suspect_fraud_flag),
                                            thirdPartyCheckFailed            = ResponseHelper.ParseTpcResult(v.tpcResult),
                                            thirdPartyMixedDepositReturnFlag =
                                                ResponseHelper.ParseStringAsBool(v.tpcMixedDepRet),
                                            thirdPartyPoolFlag =
                                                ResponseHelper.ParseStringAsBool(v.fxa_tpc_suspense_pool_flag),
                                            transactionLinkNumber  = ResponseHelper.TrimString(v.transactionLinkNumber),
                                            unencodedECDReturnFlag =
                                                ResponseHelper.ParseStringAsBool(v.fxa_unencoded_ECD_return),
                                            unprocessable           = ResponseHelper.ParseStringAsBool(v.unproc_flag),
                                            voucherDelayedIndicator = ResponseHelper.TrimString(v.voucherIndicatorField),
                                            operatorId = ResponseHelper.TrimString(v.op_id),
                                            adjustedBy = ResponseHelper.TrimString(v.op_id),
                                            adjustmentLetterRequired =
                                                ResponseHelper.ParseStringAsBool(v.adjustmentLetterRequired),
                                            forValueType = ForValueTypeEnum.Inward_Non_For_Value,
                                            postTransmissionQaAmountFlag =
                                                ResponseHelper.ParseStringAsBool(v.fxaPtQAAmtFlag),
                                            postTransmissionQaCodelineFlag =
                                                ResponseHelper.ParseStringAsBool(v.fxaPtQACodelineFlag),
                                            adjustmentReasonCode  = ResponseHelper.ParseStringAsInt(v.adjustmentReasonCode),
                                            adjustmentDescription = ResponseHelper.TrimString(v.adjustmentDescription)
                                        },

                                        voucher = new Voucher
                                        {
                                            accountNumber           = ResponseHelper.TrimString(v.acc_num),
                                            amount                  = ResponseHelper.ParseAmountField(v.amount),
                                            auxDom                  = ResponseHelper.TrimString(v.ser_num),
                                            bsbNumber               = v.bsb_num,
                                            documentReferenceNumber =
                                                ResponseHelper.ResolveDocumentReferenceNumber(
                                                    ResponseHelper.TrimString(v.doc_ref_num)),
                                            documentType   = ResponseHelper.ParseDocumentType(v.doc_type),
                                            extraAuxDom    = ResponseHelper.TrimString(v.ead),
                                            processingDate =
                                                DateTime.ParseExact(string.Format("{0}", v.proc_date), "yyyyMMdd",
                                                                    CultureInfo.InvariantCulture),
                                            transactionCode = ResponseHelper.TrimString(v.trancode),
                                        }
                                    }).ToArray(),

                                    generatedVoucher = generatedVouchers.Select(v => new VoucherInformation()
                                    {
                                        voucherBatch = new VoucherBatch
                                        {
                                            batchAccountNumber = v.batchAccountNumber,
                                            batchType          = ResponseHelper.TrimString(v.batch_type),
                                            captureBsb         = v.captureBSB,
                                            collectingBank     = v.collecting_bank,
                                            processingState    =
                                                ResponseHelper.ParseState(ResponseHelper.TrimString(v.processing_state)),
                                            scannedBatchNumber = completedBatch.S_BATCH,
                                            unitID             = originalVouchers.First().unit_id,
                                            workType           =
                                                ResponseHelper.ParseWorkType(
                                                    ResponseHelper.TrimString(completedBatch.S_JOB_ID)),
                                            subBatchType = ResponseHelper.TrimString(v.sub_batch_type),
                                        },

                                        voucherProcess = new VoucherProcess
                                        {
                                            adjustedFlag        = ResponseHelper.ParseStringAsBool(v.adjustedFlag),
                                            highValueFlag       = ResponseHelper.ParseStringAsBool(v.highValueFlag),
                                            isGeneratedVoucher  = ResponseHelper.ParseStringAsBool(v.isGeneratedVoucher),
                                            manualRepair        = ResponseHelper.ParseStringAsInt(v.man_rep_ind),
                                            preAdjustmentAmount = ResponseHelper.ParseAmountField(v.orig_amount),
                                            presentationMode    = ResponseHelper.TrimString(v.presentationMode),
                                            rawMICR             = ResponseHelper.TrimString(v.raw_micr),
                                            rawOCR                   = ResponseHelper.TrimString(v.raw_ocr),
                                            repostFromDRN            = ResponseHelper.TrimString(v.repostFromDRN),
                                            repostFromProcessingDate =
                                                ResponseHelper.ParseDateField(v.repostFromProcessingDate),
                                            surplusItemFlag                  = ResponseHelper.ParseStringAsBool(v.surplusItemFlag),
                                            suspectFraud                     = ResponseHelper.ParseStringAsBool(v.micr_suspect_fraud_flag),
                                            thirdPartyCheckFailed            = ResponseHelper.ParseTpcResult(v.tpcResult),
                                            thirdPartyMixedDepositReturnFlag =
                                                ResponseHelper.ParseStringAsBool(v.tpcMixedDepRet),
                                            thirdPartyPoolFlag =
                                                ResponseHelper.ParseStringAsBool(v.fxa_tpc_suspense_pool_flag),
                                            transactionLinkNumber  = ResponseHelper.TrimString(v.transactionLinkNumber),
                                            unencodedECDReturnFlag =
                                                ResponseHelper.ParseStringAsBool(v.fxa_unencoded_ECD_return),
                                            unprocessable           = ResponseHelper.ParseStringAsBool(v.unproc_flag),
                                            voucherDelayedIndicator = ResponseHelper.TrimString(v.voucherIndicatorField),
                                            operatorId = ResponseHelper.TrimString(v.op_id),
                                            adjustedBy = ResponseHelper.TrimString(v.op_id),
                                            adjustmentLetterRequired =
                                                ResponseHelper.ParseStringAsBool(v.adjustmentLetterRequired),
                                            forValueType = ForValueTypeEnum.Inward_Non_For_Value,
                                            postTransmissionQaAmountFlag =
                                                ResponseHelper.ParseStringAsBool(v.fxaPtQAAmtFlag),
                                            postTransmissionQaCodelineFlag =
                                                ResponseHelper.ParseStringAsBool(v.fxaPtQACodelineFlag),
                                            adjustmentReasonCode  = ResponseHelper.ParseStringAsInt(v.adjustmentReasonCode),
                                            adjustmentDescription = ResponseHelper.TrimString(v.adjustmentDescription)
                                        },

                                        voucher = new Voucher
                                        {
                                            accountNumber           = ResponseHelper.TrimString(v.acc_num),
                                            amount                  = ResponseHelper.ParseAmountField(v.amount),
                                            auxDom                  = ResponseHelper.TrimString(v.ser_num),
                                            bsbNumber               = v.bsb_num,
                                            documentReferenceNumber =
                                                ResponseHelper.ResolveDocumentReferenceNumber(
                                                    ResponseHelper.TrimString(v.doc_ref_num)),
                                            documentType   = ResponseHelper.ParseDocumentType(v.doc_type),
                                            extraAuxDom    = ResponseHelper.TrimString(v.ead),
                                            processingDate =
                                                DateTime.ParseExact(string.Format("{0}", v.proc_date), "yyyyMMdd",
                                                                    CultureInfo.InvariantCulture),
                                            transactionCode = ResponseHelper.TrimString(v.trancode),
                                        }
                                    }).ToArray()
                                };

                                if (Configuration.DeleteDatabaseRows)
                                {
                                    ResponseHelper.CleanupBatchData(batchNumber, dbContext);
                                }

                                if (string.IsNullOrEmpty(routingKey))
                                {
                                    routingKey = string.Empty;
                                }

                                Exchange.SendMessage(CustomJsonSerializer.MessageToBytes(batchResponse), routingKey.Trim(), completedBatch.CorrelationId);

                                tx.Commit();

                                Log.Debug(
                                    "Generate corresponding voucher batch '{@batch}' has been completed and a response has been placed on the queue",
                                    completedBatch.S_BATCH);
                                Log.Information("Batch '{@batch}' response sent: {@response}", completedBatch.S_BATCH,
                                                batchResponse);
                            }
                            catch (OptimisticConcurrencyException)
                            {
                                //this is to handle the race condition where more than instance of this service is running at the same time and tries to update the row.

                                //basically ignore the message by loggin a warning and rolling back.
                                //if this row was not included by mistake (e.g. it should be included), it will just come in in the next batch run.
                                Log.Warning(
                                    "Could not create a generate corresponding voucher response for batch '{@batch}' because the DIPS database row was updated by another connection",
                                    completedBatch.S_BATCH);

                                tx.Rollback();
                            }
                            catch (Exception ex)
                            {
                                Log.Error(
                                    ex,
                                    "Could not complete and create a generate corresponding voucher response for batch '{@batch}'",
                                    completedBatch.S_BATCH);
                                tx.Rollback();
                            }
                        }
                    }
                }
            }
            Log.Information("Finished processing completed generate corresponding voucher batches");
        }
Esempio n. 2
0
        /// <summary>
        /// Identify customer link number groups, create GenerateBulkCreditResponse elements for each distinct customer link number (i.e. the bulk credit and all other related vouchers)
        /// </summary>
        /// <param name="context"></param>
        public void Execute(IJobExecutionContext context)
        {
            Log.Information("Scanning database for completed generate bulk credit vouchers");

            using (var lifetimeScope = component.BeginLifetimeScope())
            {
                using (var dipsDbContext = dbContext ?? lifetimeScope.Resolve <IDipsDbContext>())
                {
                    // Get all the potential batches that have been completed
                    var completedBatches =
                        dipsDbContext.Queues
                        .Where(q =>
                               !q.ResponseCompleted &&
                               q.S_LOCATION == DipsLocationType.GenerateBulkCreditVoucherDone.Value &&
                               q.S_LOCK.Trim() == "0")
                        .ToList();

                    Log.Information("Found {0} completed generate bulk credit vouchers", completedBatches.Count);

                    foreach (var completedBatch in completedBatches)
                    {
                        Log.Debug("Creating response for batch {@batch}", completedBatch.S_BATCH);

                        // only commit the transaction if
                        // a) we were the first application to mark this batch row as CorrectCodelineCompleted (DipsQueue uses optimistic concurrency)
                        // b) we were able to place a response message on the bus
                        using (var tx = dipsDbContext.BeginTransaction())
                        {
                            try
                            {
                                // mark the line as completed
                                completedBatch.ResponseCompleted = true;
                                var routingKey = completedBatch.RoutingKey;

                                dipsDbContext.SaveChanges();

                                var batchNumber = completedBatch.S_BATCH;

                                var customerLinkBatches = dipsDbContext.NabChqPods.Where(n => n.S_BATCH == batchNumber).Select(n => new { n.customerLinkNumber }).Distinct().ToList();

                                var batchResponse = new GenerateBatchBulkCreditResponse();
                                List <GenerateBulkCreditResponse> bulkCredit = new List <GenerateBulkCreditResponse>();

                                var voucherBatch = dipsDbContext.NabChqPods
                                                   .Where(
                                    v => v.S_BATCH == batchNumber)
                                                   .ToList();

                                foreach (var customerLinkBatch in customerLinkBatches)
                                {
                                    var vouchers = voucherBatch.Where(v => v.customerLinkNumber == customerLinkBatch.customerLinkNumber).ToList();

                                    bulkCredit.AddRange(GenerateBulkCreditResponse(completedBatch, vouchers));
                                }

                                batchResponse.transactions = bulkCredit.ToArray();

                                if (adapterConfiguration.DeleteDatabaseRows)
                                {
                                    ResponseHelper.CleanupBatchData(batchNumber, dipsDbContext);
                                }

                                if (string.IsNullOrEmpty(routingKey))
                                {
                                    routingKey = string.Empty;
                                }

                                Task.WaitAll(responseExchange.PublishAsync(batchResponse, completedBatch.CorrelationId,
                                                                           routingKey.Trim()));

                                tx.Commit();

                                Log.Debug(
                                    "Generate bulk credit voucher batch '{@batch}' has been completed and a response has been placed on the queue",
                                    completedBatch.S_BATCH);
                                Log.Information("Batch '{@batch}' response sent: {@response}", completedBatch.S_BATCH,
                                                batchResponse.transactions); // note - Serilog does not seem able to output the batchResponse object
                            }
                            catch (OptimisticConcurrencyException)
                            {
                                //this is to handle the race condition where more than instance of this service is running at the same time and tries to update the row.
                                //basically ignore the message by loggin a warning and rolling back.
                                //if this row was not included by mistake (e.g. it should be included), it will just come in in the next batch run.
                                Log.Warning(
                                    "Could not create a generate bulk credit voucher response for batch '{@batch}' because the DIPS database row was updated by another connection",
                                    completedBatch.S_BATCH);

                                tx.Rollback();
                            }
                            catch (Exception ex)
                            {
                                Log.Error(
                                    ex,
                                    "Could not complete and create a generate bulk credit voucher response for batch '{@batch}'",
                                    completedBatch.S_BATCH);
                                tx.Rollback();
                            }
                        }
                    }
                }
            }

            Log.Information("Finished processing completed generate bulk credit voucher batches");
        }
        public override void ExecuteJob()
        {
            using (var dbConnection = new SqlConnection(Configuration.SqlConnectionString))
            {
                using (var dbContext = new DipsDbContext(dbConnection))
                {
                    Log.Information("Scanning database for completed codeline validation batches");
                    //Get all the potential batches that have been completed
                    var completedBatches =
                        dbContext.Queues
                        .Where(q =>
                               !q.ResponseCompleted &&
                               q.S_LOCATION == DipsLocationType.CodelineValidationDone.Value &&
                               q.S_LOCK.Trim() == "0")
                        .ToList();

                    Serilog.Log.Information("Found {0} completed codeline validation batches", completedBatches.Count());

                    foreach (var completedBatch in completedBatches)
                    {
                        string routingKey;
                        Serilog.Log.Debug("Creating response for batch {@batch}", completedBatch.S_BATCH);

                        //only commit the transaction if
                        // a) we were the first application to mark this batch row as ValidateCodelineCompleted (DipsQueue uses optimistic concurrency)
                        // b) we were able to place a response message on the bus
                        using (var tx = dbContext.BeginTransaction())
                        {
                            try
                            {
                                //mark the batch as completed so it gets 'locked'
                                completedBatch.ResponseCompleted = true;
                                routingKey = completedBatch.RoutingKey;

                                dbContext.SaveChanges();

                                var batchNumber = completedBatch.S_BATCH;

                                //get the vouchers, generate and send the response
                                var vouchers = dbContext.NabChqPods
                                               .Where(v => v.S_BATCH == batchNumber)
                                               .AsEnumerable()
                                               .Select(v => new
                                {
                                    S_STATUS1 =
                                        int.Parse(string.IsNullOrWhiteSpace(v.S_STATUS1) ? "0" : v.S_STATUS1),
                                    voucher = v
                                }).ToList();

                                //use bitmasks to map the values from S_STATUS1 field
                                var batchResponse = new ValidateBatchCodelineResponse
                                {
                                    voucherBatch = new VoucherBatch
                                    {
                                        scannedBatchNumber = completedBatch.S_BATCH,
                                        workType           =
                                            ResponseHelper.ParseWorkType(
                                                ResponseHelper.TrimString(completedBatch.S_JOB_ID)),
                                        batchAccountNumber = vouchers.First().voucher.batchAccountNumber,
                                        captureBsb         = vouchers.First().voucher.captureBSB,
                                        processingState    =
                                            ResponseHelper.ParseState(
                                                ResponseHelper.TrimString(vouchers.First().voucher.processing_state)),
                                        collectingBank = vouchers.First().voucher.collecting_bank,
                                        unitID         = vouchers.First().voucher.unit_id,
                                        batchType      = ResponseHelper.TrimString(vouchers.First().voucher.batch_type),
                                        subBatchType   =
                                            ResponseHelper.TrimString(vouchers.First().voucher.sub_batch_type),
                                    },
                                    voucher = vouchers.Select(v => new ValidateCodelineResponse
                                    {
                                        extraAuxDomStatus   = DipsStatus1Bitmask.GetExtraAuxDomStatusMasked(v.S_STATUS1),
                                        auxDomStatus        = DipsStatus1Bitmask.GetAuxDomStatusMasked(v.S_STATUS1),
                                        accountNumberStatus =
                                            DipsStatus1Bitmask.GetAccountNumberStatusMasked(v.S_STATUS1),
                                        amountStatus          = DipsStatus1Bitmask.GetAmountStatusMasked(v.S_STATUS1),
                                        bsbNumberStatus       = DipsStatus1Bitmask.GetBsbNumberStatusMasked(v.S_STATUS1),
                                        transactionCodeStatus =
                                            DipsStatus1Bitmask.GetTransactionCodeStatusMasked(v.S_STATUS1),
                                        documentReferenceNumber =
                                            ResponseHelper.ResolveDocumentReferenceNumber(
                                                ResponseHelper.TrimString(v.voucher.doc_ref_num)),
                                        targetEndPoint = ResponseHelper.TrimString(v.voucher.ie_endPoint),
                                        documentType   = ResponseHelper.ParseDocumentType(v.voucher.doc_type),
                                        processingDate =
                                            DateTime.ParseExact(string.Format("{0}", v.voucher.proc_date), "yyyyMMdd",
                                                                CultureInfo.InvariantCulture),
                                    }).ToArray()
                                };


                                if (Configuration.DeleteDatabaseRows)
                                {
                                    ResponseHelper.CleanupBatchData(batchNumber, dbContext);
                                }

                                if (string.IsNullOrEmpty(routingKey))
                                {
                                    routingKey = string.Empty;
                                }

                                //Task.WaitAll(responseExchange.PublishAsync(batchResponse, completedBatch.CorrelationId, routingKey.Trim()));

                                tx.Commit();

                                Serilog.Log.Debug(
                                    "Codeline validation batch '{@batch}' has been completed and a response has been placed on the queue",
                                    completedBatch.S_BATCH);
                                Serilog.Log.Information("Batch '{@batch}' response sent: {@response}",
                                                        completedBatch.S_BATCH, batchResponse);
                            }
                            catch (OptimisticConcurrencyException)
                            {
                                //this is to handle the race condition where more than instance of this service is running at the same time and tries to update the row.

                                //basically ignore the message by loggin a warning and roll back.
                                //if this row was not included by mistake (e.g. it should be included), it will just come in in the next batch run.
                                Serilog.Log.Warning(
                                    "Could not create a codeline validation response for batch '{@batch}' because the DIPS database row was updated by another connection",
                                    completedBatch.S_BATCH);

                                tx.Rollback();
                            }
                            catch (Exception ex)
                            {
                                Serilog.Log.Error(
                                    ex,
                                    "Could not complete and create a codeline validation response for batch '{@batch}'",
                                    completedBatch.S_BATCH);
                                tx.Rollback();
                            }
                        }
                    }
                }
            }
        }
        public void Execute(IJobExecutionContext context)
        {
            Log.Information("Scanning database for completed codeline correction batches");

            using (var lifetimeScope = component.BeginLifetimeScope())
            {
                using (var dipsDbContext = dbContext ?? lifetimeScope.Resolve <IDipsDbContext>())
                {
                    //Get all the potential batches that have been completed
                    var completedBatches =
                        dipsDbContext.Queues
                        .Where(q =>
                               !q.ResponseCompleted &&
                               q.S_LOCATION == DipsLocationType.CodelineCorrectionDone.Value &&
                               q.S_LOCK.Trim() == "0")
                        .ToList();

                    Log.Information("Found {0} completed codeline correction batches", completedBatches.Count);

                    foreach (var completedBatch in completedBatches)
                    {
                        Log.Debug("Creating response for batch {@batch}", completedBatch.S_BATCH);

                        //only commit the transaction if
                        // a) we were the first application to mark this batch row as CorrectCodelineCompleted (DipsQueue uses optimistic concurrency)
                        // b) we were able to place a response message on the bus
                        using (var tx = dipsDbContext.BeginTransaction())
                        {
                            try
                            {
                                //mark the line as completed
                                completedBatch.ResponseCompleted = true;
                                var routingKey = completedBatch.RoutingKey;

                                dipsDbContext.SaveChanges();

                                var batchNumber = completedBatch.S_BATCH;

                                //get the vouchers, generate and send the response
                                var vouchers = dipsDbContext.NabChqPods
                                               .Where(
                                    v =>
                                    v.S_BATCH == batchNumber && v.S_DEL_IND != "  255" &&
                                    (v.export_exclude_flag.Trim() != "1"))
                                               .ToList();

                                if (vouchers.Count > 0)
                                {
                                    var firstVoucher =
                                        vouchers.First(v => !ResponseHelper.ParseStringAsBool(v.isGeneratedVoucher));

                                    var batchResponse = new CorrectBatchCodelineResponse
                                    {
                                        voucherBatch = new VoucherBatch
                                        {
                                            batchAccountNumber = firstVoucher.batchAccountNumber,
                                            batchType          = ResponseHelper.TrimString(firstVoucher.batch_type),
                                            captureBsb         = firstVoucher.captureBSB,
                                            collectingBank     = firstVoucher.collecting_bank,
                                            processingState    =
                                                ResponseHelper.ParseState(
                                                    ResponseHelper.TrimString(firstVoucher.processing_state)),
                                            scannedBatchNumber = completedBatch.S_BATCH,
                                            unitID             = firstVoucher.unit_id,
                                            workType           =
                                                ResponseHelper.ParseWorkType(
                                                    ResponseHelper.TrimString(completedBatch.S_JOB_ID)),
                                            subBatchType = ResponseHelper.TrimString(firstVoucher.sub_batch_type),
                                        },
                                        voucher = vouchers.Select(v => new CorrectCodelineResponse
                                        {
                                            accountNumber                = ResponseHelper.TrimString(v.acc_num),
                                            amount                       = ResponseHelper.ParseAmountField(v.amount),
                                            auxDom                       = ResponseHelper.TrimString(v.ser_num),
                                            bsbNumber                    = v.bsb_num,
                                            dips_override                = ResponseHelper.TrimString(v.@override),
                                            documentReferenceNumber      = ResponseHelper.TrimString(v.doc_ref_num),
                                            documentType                 = ResponseHelper.ParseDocumentType(v.doc_type),
                                            extraAuxDom                  = ResponseHelper.TrimString(v.ead),
                                            forValueIndicator            = ResponseHelper.TrimString(v.fv_ind),
                                            manualRepair                 = ResponseHelper.ParseStringAsInt(v.man_rep_ind),
                                            postTransmissionQaAmountFlag =
                                                ResponseHelper.ParseStringAsBool(v.fxaPtQAAmtFlag),
                                            postTransmissionQaCodelineFlag =
                                                ResponseHelper.ParseStringAsBool(v.fxaPtQACodelineFlag),
                                            presentationMode = ResponseHelper.TrimString(v.presentationMode),
                                            processingDate   =
                                                DateTime.ParseExact(string.Format("{0}", v.proc_date), "yyyyMMdd",
                                                                    CultureInfo.InvariantCulture),
                                            repostFromDRN            = ResponseHelper.TrimString(v.repostFromDRN),
                                            repostFromProcessingDate =
                                                ResponseHelper.ParseDateField(v.repostFromProcessingDate),
                                            targetEndPoint  = ResponseHelper.TrimString(v.ie_endPoint),
                                            transactionCode = ResponseHelper.TrimString(v.trancode),
                                            transactionLink = ResponseHelper.TrimString(v.transactionLinkNumber),
                                            unprocessable   = ResponseHelper.ParseStringAsBool(v.unproc_flag),
                                            operatorID      = ResponseHelper.TrimString(v.op_id),
                                            collectingBank  = ResponseHelper.TrimString(v.collecting_bank),

                                            creditNoteFlag = ResponseHelper.ParseStringAsBool(v.creditNoteFlag)
                                        }).ToArray()
                                    };

                                    if (adapterConfiguration.DeleteDatabaseRows)
                                    {
                                        ResponseHelper.CleanupBatchData(batchNumber, dipsDbContext);
                                    }

                                    if (string.IsNullOrEmpty(routingKey))
                                    {
                                        routingKey = string.Empty;
                                    }

                                    Task.WaitAll(responseExchange.PublishAsync(batchResponse,
                                                                               completedBatch.CorrelationId,
                                                                               routingKey.Trim()));

                                    tx.Commit();

                                    Log.Debug(
                                        "Codeline correction batch '{@batch}' has been completed and a response has been placed on the queue",
                                        completedBatch.S_BATCH);
                                    Log.Information("Batch '{@batch}' response sent: {@response}",
                                                    completedBatch.S_BATCH,
                                                    batchResponse);
                                }
                                else
                                {
                                    Log.Error(
                                        "Could not create a codeline correction response for batch '{@batch}' because the vouchers cannot be queried",
                                        completedBatch.S_BATCH);
                                }
                            }
                            catch (OptimisticConcurrencyException)
                            {
                                //this is to handle the race condition where more than instance of this service is running at the same time and tries to update the row.

                                //basically ignore the message by loggin a warning and rolling back.
                                //if this row was not included by mistake (e.g. it should be included), it will just come in in the next batch run.
                                Log.Warning(
                                    "Could not create a codeline correction response for batch '{@batch}' because the DIPS database row was updated by another connection",
                                    completedBatch.S_BATCH);

                                tx.Rollback();
                            }
                            catch (Exception ex)
                            {
                                Log.Error(
                                    ex,
                                    "Could not complete and create a codeline correction response for batch '{@batch}'",
                                    completedBatch.S_BATCH);
                                tx.Rollback();
                            }
                        }
                    }
                }
            }

            Log.Information("Finished processing completed codeline correction batches");
        }
        public override void ExecuteJob()
        {
            Log.Information("Scanning database for completed transaction validation batches");

            using (var dbConnection = new SqlConnection(Configuration.SqlConnectionString))
            {
                using (var dbContext = new DipsDbContext(dbConnection))
                {
                    //Get all the potential batches that have been completed
                    var completedBatches =
                        dbContext.Queues
                        .Where(q =>
                               !q.ResponseCompleted &&
                               q.S_LOCATION == DipsLocationType.TransactionValidationDone.Value &&
                               q.S_LOCK.Trim() == "0")
                        .ToList();

                    Log.Information("Found {0} completed transaction validation batches", completedBatches.Count());

                    foreach (var completedBatch in completedBatches)
                    {
                        Log.Debug("Creating response for batch {@batch}", completedBatch.S_BATCH);

                        //only commit the transaction if
                        // a) we were the first application to mark this batch row as ValidateTransactionCompleted (DipsQueue uses optimistic concurrency)
                        // b) we were able to place a response message on the bus
                        using (var tx = dbContext.BeginTransaction())
                        {
                            try
                            {
                                //mark the batch as completed so it gets 'locked'
                                completedBatch.ResponseCompleted = true;
                                var routingKey = completedBatch.RoutingKey;

                                dbContext.SaveChanges();

                                var batchNumber = completedBatch.S_BATCH;

                                //get the vouchers, generate and send the response
                                var vouchers = dbContext.NabChqPods
                                               .Where(v => v.S_BATCH == batchNumber && v.S_DEL_IND != "  255")
                                               .ToList()
                                               .Select(v => new
                                {
                                    S_STATUS1 = int.Parse(string.IsNullOrWhiteSpace(v.S_STATUS1) ? "0" : v.S_STATUS1),
                                    voucher   = v
                                }).ToList();

                                if (vouchers.Count > 0)
                                {
                                    var firstVoucher = vouchers.First(v => v.voucher.isGeneratedVoucher != "1");

                                    //use bitmasks to map the values from S_STATUS1 field
                                    var batchResponse = new ValidateBatchTransactionResponse
                                    {
                                        voucherBatch = new VoucherBatch
                                        {
                                            scannedBatchNumber = completedBatch.S_BATCH,
                                            workType           = ResponseHelper.ParseWorkType(ResponseHelper.TrimString(completedBatch.S_JOB_ID)),
                                            batchAccountNumber = firstVoucher.voucher.batchAccountNumber,
                                            captureBsb         = firstVoucher.voucher.captureBSB,
                                            processingState    = ResponseHelper.ParseState(ResponseHelper.TrimString(firstVoucher.voucher.processing_state)),
                                            collectingBank     = firstVoucher.voucher.collecting_bank,
                                            unitID             = firstVoucher.voucher.unit_id,
                                            batchType          = ResponseHelper.TrimString(firstVoucher.voucher.batch_type),
                                            subBatchType       = ResponseHelper.TrimString(firstVoucher.voucher.sub_batch_type),
                                        },
                                        voucher = vouchers.Select(v => new ValidateTransactionResponse
                                        {
                                            documentReferenceNumber = v.voucher.S_TRACE,
                                            surplusItemFlag         = ResponseHelper.ParseStringAsBool(v.voucher.surplusItemFlag),
                                            suspectFraudFlag        = ResponseHelper.ParseStringAsBool(v.voucher.micr_suspect_fraud_flag),
                                            isGeneratedVoucher      = ResponseHelper.ParseStringAsBool(v.voucher.isGeneratedVoucher),
                                            codelineFieldsStatus    = new CodelineStatus
                                            {
                                                extraAuxDomStatus     = DipsStatus1Bitmask.GetExtraAuxDomStatusMasked(v.S_STATUS1),
                                                auxDomStatus          = DipsStatus1Bitmask.GetAuxDomStatusMasked(v.S_STATUS1),
                                                accountNumberStatus   = DipsStatus1Bitmask.GetAccountNumberStatusMasked(v.S_STATUS1),
                                                amountStatus          = DipsStatus1Bitmask.GetAmountStatusMasked(v.S_STATUS1),
                                                bsbNumberStatus       = DipsStatus1Bitmask.GetBsbNumberStatusMasked(v.S_STATUS1),
                                                transactionCodeStatus = DipsStatus1Bitmask.GetTransactionCodeStatusMasked(v.S_STATUS1),
                                            },
                                            reasonCode                       = ResponseHelper.GetExpertBalanceReason(v.voucher.balanceReason),
                                            transactionLinkNumber            = ResponseHelper.TrimString(v.voucher.transactionLinkNumber),
                                            unprocessable                    = ResponseHelper.ParseStringAsBool(v.voucher.unproc_flag),
                                            forValueIndicator                = ResponseHelper.TrimString(v.voucher.fv_ind),
                                            dips_override                    = ResponseHelper.TrimString(v.voucher.@override),
                                            thirdPartyCheckRequired          = ResponseHelper.ParseYNStringAsBool(v.voucher.tpcRequired),
                                            unencodedECDReturnFlag           = ResponseHelper.ParseStringAsBool(v.voucher.fxa_unencoded_ECD_return),
                                            thirdPartyMixedDepositReturnFlag = ResponseHelper.ParseStringAsBool(v.voucher.tpcMixedDepRet),
                                            postTransmissionQaAmountFlag     = ResponseHelper.ParseStringAsBool(v.voucher.fxaPtQAAmtFlag),
                                            postTransmissionQaCodelineFlag   = ResponseHelper.ParseStringAsBool(v.voucher.fxaPtQACodelineFlag),
                                            voucher = new Voucher
                                            {
                                                accountNumber = ResponseHelper.TrimString(v.voucher.acc_num),
                                                amount        = ResponseHelper.ParseAmountField(v.voucher.amount),
                                                auxDom        = ResponseHelper.TrimString(v.voucher.ser_num),
                                                bsbNumber     = v.voucher.bsb_num,
                                                //DIPS overwrites doc_ref_num with empty values during auto balancing ..
                                                //documentReferenceNumber = ResponseHelper.ResolveDocumentReferenceNumber(ResponseHelper.TrimString(v.voucher.doc_ref_num)),
                                                documentReferenceNumber = ResponseHelper.ResolveDocumentReferenceNumber(v.voucher.S_TRACE.Trim()),
                                                extraAuxDom             = ResponseHelper.TrimString(v.voucher.ead),
                                                transactionCode         = ResponseHelper.TrimString(v.voucher.trancode),
                                                documentType            = ResponseHelper.ParseDocumentType(v.voucher.doc_type),
                                                processingDate          = DateTime.ParseExact(string.Format("{0}{1}", completedBatch.S_SDATE, completedBatch.S_STIME), "dd/MM/yyHH:mm:ss", CultureInfo.InvariantCulture),
                                            }
                                        }).ToArray()
                                    };

                                    if (Configuration.DeleteDatabaseRows)
                                    {
                                        ResponseHelper.CleanupBatchData(batchNumber, dbContext);
                                    }

                                    if (string.IsNullOrEmpty(routingKey))
                                    {
                                        routingKey = string.Empty;
                                    }

                                    Exchange.SendMessage(CustomJsonSerializer.MessageToBytes(batchResponse), routingKey.Trim(), completedBatch.CorrelationId);
                                    //Task.WaitAll(responseExchange.PublishAsync(batchResponse, completedBatch.CorrelationId, routingKey.Trim()));

                                    tx.Commit();

                                    Log.Debug("Transaction validation batch '{@batch}' has been completed and a response has been placed on the queue", completedBatch.S_BATCH);
                                    Log.Information("Batch '{@batch}' response sent: {@response}", completedBatch.S_BATCH, batchResponse);
                                }
                                else
                                {
                                    Log.Error(
                                        "Could not create a transaction validation response for batch '{@batch}' because the vouchers cannot be queried",
                                        completedBatch.S_BATCH);
                                }
                            }
                            catch (OptimisticConcurrencyException)
                            {
                                //this is to handle the race condition where more than instance of this service is running at the same time and tries to update the row.

                                //basically ignore the message by loggin a warning and roll back.
                                //if this row was not included by mistake (e.g. it should be included), it will just come in in the next batch run.
                                Log.Warning(
                                    "Could not create a transaction validation response for batch '{@batch}' because the DIPS database row was updated by another connection",
                                    completedBatch.S_BATCH);

                                tx.Rollback();
                            }
                            catch (Exception ex)
                            {
                                Log.Error(
                                    ex,
                                    "Could not complete and create an transaction validation response for batch '{@batch}'",
                                    completedBatch.S_BATCH);
                                tx.Rollback();
                            }
                        }
                    }
                }
            }
            Log.Information("Finished processing completed transaction validation batches");
        }
        public void Execute(IJobExecutionContext context)
        {
            Log.Information("Scanning database for completed transaction correction batches");

            using (var lifetimeScope = component.BeginLifetimeScope())
            {
                using (var dipsDbContext = dbContext ?? lifetimeScope.Resolve <IDipsDbContext>())
                {
                    //Get all the potential batches that have been completed
                    var completedBatches =
                        dipsDbContext.Queues
                        .Where(q =>
                               !q.ResponseCompleted &&
                               q.S_LOCATION == DipsLocationType.TransactionCorrectionDone.Value &&
                               q.S_LOCK.Trim() == "0")
                        .ToList();

                    Log.Information("Found {0} completed transaction correction batches", completedBatches.Count);

                    foreach (var completedBatch in completedBatches)
                    {
                        Log.Debug("Creating response for batch {@batch}", completedBatch.S_BATCH);

                        //only commit the transaction if
                        // a) we were the first application to mark this batch row as CorrectTransactionCompleted (DipsQueue uses optimistic concurrency)
                        // b) we were able to place a response message on the bus
                        using (var tx = dipsDbContext.BeginTransaction())
                        {
                            try
                            {
                                //mark the batch as completed so it gets 'locked'
                                completedBatch.ResponseCompleted = true;
                                var routingKey = completedBatch.RoutingKey;

                                dipsDbContext.SaveChanges();

                                var batchNumber = completedBatch.S_BATCH;

                                //get the vouchers, generate and send the response
                                var vouchers = dipsDbContext.NabChqPods
                                               .Where(v =>
                                                      v.S_BATCH == batchNumber &&
                                                      v.S_DEL_IND != "  255")
                                               .ToList();

                                var firstVoucher = vouchers.First(v => v.isGeneratedVoucher != "1");

                                //use bitmasks to map the values from S_STATUS1 field
                                var batchResponse = new CorrectBatchTransactionResponse
                                {
                                    voucherBatch = new VoucherBatch
                                    {
                                        batchAccountNumber = firstVoucher.batchAccountNumber,
                                        batchType          = ResponseHelper.TrimString(firstVoucher.batch_type),
                                        captureBsb         = firstVoucher.captureBSB,
                                        collectingBank     = firstVoucher.collecting_bank,
                                        processingState    =
                                            ResponseHelper.ParseState(
                                                ResponseHelper.TrimString(firstVoucher.processing_state)),
                                        scannedBatchNumber = completedBatch.S_BATCH,
                                        unitID             = firstVoucher.unit_id,
                                        workType           =
                                            ResponseHelper.ParseWorkType(
                                                ResponseHelper.TrimString(completedBatch.S_JOB_ID)),
                                        subBatchType = ResponseHelper.TrimString(firstVoucher.sub_batch_type),
                                    },
                                    voucher = vouchers.Select(v => new CorrectTransactionResponse
                                    {
                                        adjustedBy               = ResponseHelper.TrimString(v.adjustedBy),
                                        adjustedFlag             = ResponseHelper.ParseStringAsBool(v.adjustedFlag),
                                        adjustmentDescription    = ResponseHelper.TrimString(v.adjustmentDescription),
                                        adjustmentLetterRequired =
                                            ResponseHelper.ParseStringAsBool(v.adjustmentLetterRequired),
                                        adjustmentReasonCode         = ResponseHelper.ParseStringAsInt(v.adjustmentReasonCode),
                                        dips_override                = ResponseHelper.TrimString(v.@override),
                                        forValueIndicator            = ResponseHelper.TrimString(v.fv_ind),
                                        highValueFlag                = ResponseHelper.ParseStringAsBool(v.highValueFlag),
                                        isGeneratedVoucher           = ResponseHelper.ParseStringAsBool(v.isGeneratedVoucher),
                                        manualRepair                 = ResponseHelper.ParseStringAsInt(v.man_rep_ind),
                                        operatorId                   = ResponseHelper.TrimString(v.op_id),
                                        postTransmissionQaAmountFlag =
                                            ResponseHelper.ParseStringAsBool(v.fxaPtQAAmtFlag),
                                        postTransmissionQaCodelineFlag =
                                            ResponseHelper.ParseStringAsBool(v.fxaPtQACodelineFlag),
                                        preAdjustmentAmount = ResponseHelper.ParseAmountField(v.orig_amount),
                                        presentationMode    = ResponseHelper.TrimString(v.presentationMode),
                                        surplusItemFlag     = ResponseHelper.ParseStringAsBool(v.surplusItemFlag),
                                        suspectFraudFlag    =
                                            ResponseHelper.ParseOverloadedSuspectFraudFlag(v.micr_suspect_fraud_flag),
                                        targetEndPoint                   = ResponseHelper.TrimString(v.ie_endPoint),
                                        thirdPartyCheckRequired          = ResponseHelper.ParseYNStringAsBool(v.tpcRequired),
                                        thirdPartyMixedDepositReturnFlag =
                                            ResponseHelper.ParseStringAsBool(v.tpcMixedDepRet),
                                        transactionLinkNumber  = ResponseHelper.TrimString(v.transactionLinkNumber),
                                        unencodedECDReturnFlag =
                                            ResponseHelper.ParseStringAsBool(v.fxa_unencoded_ECD_return),
                                        unprocessable            = ResponseHelper.ParseStringAsBool(v.unproc_flag),
                                        voucherDelayedIndicator  = ResponseHelper.TrimString(v.delay_ind),
                                        dipsTraceNumber          = ResponseHelper.TrimString(v.S_TRACE),
                                        dipsSequenceNumber       = ResponseHelper.TrimString(v.S_SEQUENCE),
                                        listingPageNumber        = ResponseHelper.TrimString(v.listingPageNumber),
                                        isRetrievedVoucher       = ResponseHelper.ParseStringAsBool(v.isRetrievedVoucher),
                                        alternateAccountNumber   = ResponseHelper.TrimString(v.alt_acc_num),
                                        alternateAuxDom          = ResponseHelper.TrimString(v.alt_ser_num),
                                        alternateBsbNumber       = ResponseHelper.TrimString(v.alt_bsb_num),
                                        alternateExAuxDom        = ResponseHelper.TrimString(v.alt_ead),
                                        alternateTransactionCode = ResponseHelper.TrimString(v.alt_trancode),
                                        creditNoteFlag           = ResponseHelper.ParseStringAsBool(v.creditNoteFlag),
                                        insertedCreditType       = ResponseHelper.ParseInsertedCreditType(v.insertedCreditType),

                                        voucher = new Voucher
                                        {
                                            accountNumber           = ResponseHelper.TrimString(v.acc_num),
                                            amount                  = ResponseHelper.ParseAmountField(v.amount),
                                            auxDom                  = ResponseHelper.TrimString(v.ser_num),
                                            bsbNumber               = v.bsb_num,
                                            documentReferenceNumber = ResponseHelper.TrimString(v.doc_ref_num),
                                            extraAuxDom             = ResponseHelper.TrimString(v.ead),
                                            transactionCode         = ResponseHelper.TrimString(v.trancode),
                                            documentType            = ResponseHelper.ParseDocumentType(v.doc_type),
                                            processingDate          =
                                                DateTime.ParseExact(
                                                    string.Format("{0}{1}", completedBatch.S_SDATE,
                                                                  completedBatch.S_STIME),
                                                    "dd/MM/yyHH:mm:ss", CultureInfo.InvariantCulture),
                                        }
                                    }).ToArray()
                                };

                                if (adapterConfiguration.DeleteDatabaseRows)
                                {
                                    ResponseHelper.CleanupBatchData(batchNumber, dipsDbContext);
                                }

                                if (string.IsNullOrEmpty(routingKey))
                                {
                                    routingKey = string.Empty;
                                }

                                Task.WaitAll(responseExchange.PublishAsync(batchResponse, completedBatch.CorrelationId,
                                                                           routingKey.Trim()));

                                tx.Commit();

                                Log.Debug(
                                    "Transaction correction batch '{@batch}' has been completed and a response has been placed on the queue",
                                    completedBatch.S_BATCH);
                                Log.Information("Batch '{@batch}' response sent: {@response}", completedBatch.S_BATCH,
                                                batchResponse);
                            }
                            catch (OptimisticConcurrencyException)
                            {
                                //this is to handle the race condition where more than instance of this service is running at the same time and tries to update the row.

                                //basically ignore the message by loggin a warning and roll back.
                                //if this row was not included by mistake (e.g. it should be included), it will just come in in the next batch run.
                                Log.Warning(
                                    "Could not create a transaction correction response for batch '{@batch}' because the DIPS database row was updated by another connection",
                                    completedBatch.S_BATCH);

                                tx.Rollback();
                            }
                            catch (Exception ex)
                            {
                                Log.Error(
                                    ex,
                                    "Could not complete and create an transaction correction response for batch '{@batch}'",
                                    completedBatch.S_BATCH);
                                tx.Rollback();
                            }
                        }
                    }
                }
            }

            Log.Information("Finished processing completed transaction correction batches");
        }