public override void stageExecute(SalePostContext context)
        {
            SaleRepo.SaleBuilder builder  = context.saleBuild();
            PANRange             binRange = builder.getCard().getPANRange();
            Scheme scheme = schemeCheck.getSchemeFromPanRange(binRange);

            if ((binRange == null) || (scheme == null))
            {
                // TODO: Throw exception rather than this?
                context.Response.ResponseCode = ResponseCode.NO_BIN_FOR_CARD_NUMBER;
                return;
            }
            else
            {
                //Logger.info("Scheme: " + scheme.AuthScheme);
                context.Scheme = scheme;
            }
            CardDate cardExpiryDate = builder.Card.ExpiryDate;

            if (cardExpiryDate == null)
            {
                //Logger.warn("Card expiry date is outside of maximum limit");
                context.Response.ResponseCode = ResponseCode.CARD_EXPIRY_DATE_INVALID;
                return;
            }
            nextStage(context);
        }
        private ResponseCode checkSchemeFundsRecipient(PANRange binRange, Terminal terminal, FundsRecipient recipient, AuthScheme authScheme, bool debtRepayFlag)
        {
            ResponseCode?errorCode           = null;;
            bool         isVisaFinancial     = VisaMerchantClassificationGroup.FINANCAL_INSTITUTION.contains(terminal.MCC);
            bool         isVisaDebtRepayment = VisaMerchantClassificationGroup.DEBT_REPAYMENT.contains(terminal.MCC) && isDebtRepaySale;

            if ((binRange.IssueCountry == Country.GB) && (terminal.Country == Country.GB) && (((isVisaFinancial || isVisaDebtRepayment) && authScheme == AuthScheme.VISA) || (isDebtRepaySale && authScheme == AuthScheme.MASTERCARD)))
            {
                //Logger.info(authScheme.name() + " Funds Recipient data is required for this Sale");
                bool dataMissing;

                // VISA : GB merchant and shopper, and an 6012 or 7299 merchant
                // MC : if debt repayment transaction
                // Then - All FraudRecipient fields are required..
                dataMissing = (recipient == null);
                if (recipient != null)
                {
                    dataMissing |= (recipient.DateOfBirth == null);
                    dataMissing |= missingRecipientData(recipient.AccountNumber);
                    dataMissing |= missingRecipientData(recipient.PostalCode);
                    dataMissing |= missingRecipientData(recipient.Surname);
                }
                if (dataMissing)
                {
                    //Logger.info("Not all Funds Recipient data was provided");
                    errorCode = ResponseCode.FUNDSRECIPIENT_MISSING;
                }
                else
                {
                    // .. and the postcode must look like a UK one.
                    if (missingRecipientData(recipient.UKPostalCodePrefix))
                    {
                        //Logger.info("Recipient Postal code doesn't appear to be UK based");
                        errorCode = ResponseCode.FUNDSRECIPIENT_INVALID;
                    }
                }
            }
            return(errorCode.Value);
            //throw new NotImplementedException();
        }
        public virtual Scheme getSchemeFromPanRange(PANRange binRange)
        {
            if (binRange != null)
            {
                // Have a range - see what scheme it thinks it is.
                Scheme     scheme         = null;
                AuthScheme cardAuthScheme = binRange.Scheme;
                if (cardAuthScheme != null)
                {
                    switch (cardAuthScheme)
                    {
                    case AuthScheme.VISA:
                        //scheme = visaScheme;
                        break;

                    case AuthScheme.MASTERCARD:
                        //scheme = mastercardScheme;
                        break;

                    case AuthScheme.AMEX:
                        //scheme = amexScheme;
                        break;
                    }
                }
                if (scheme == null)
                {
                    //LOGGER.error("Couldn't determine AuthScheme for available PanRange");
                    return(null);
                }
                else
                {
                    return(scheme);
                }
            }
            else
            {
                //LOGGER.error("Couldn't determine PanRange scheme for card.");
                return(null);
            }
        }
        public override void stageExecute(SalePostContext context)
        {
            SalePostResponse response = context.Response;

            SaleRepo.SaleBuilder saleBuilder = context.saleBuild();
            PANRange             binRange    = null;
            Card         card = saleBuilder.Card;
            ResponseCode?failureResponseCode = null;;

            if (card != null)
            {
                binRange = card.PANRange;
            }
            if (binRange != null)
            {
                Terminal terminal = saleBuilder.Terminal;
                if (terminal != null)
                {
                    failureResponseCode = checkSchemeFundsRecipient(binRange, terminal, saleBuilder.FundsRecipient, binRange.Scheme, saleBuilder.DebtRepayFlag);
                }
                else
                {
                    //Logger.warn("Sale doesn't have associated terminal = " + "Cannot perform Funds recipient check");
                }
            }
            else
            {
                //Logger.info("Not performing FundsRecipient check - Not a VISA/Mastercard card");
            }
            //nextStage(context);
            if (failureResponseCode.HasValue)
            {
                response.ResponseCode = (ResponseCode)failureResponseCode;
            }
            else
            {
                nextStage(context);
            }
        }