public bool RecordTransaction(Transaction t)
 {
     using (SqlConnection conn = new SqlConnection(connStr))
     {
         conn.Open();
         if (conn.Execute("spTransactionRecord", TransToDynParm(t), commandType: CommandType.StoredProcedure) > 0)
             return true;
         else
             return false;
     }
 }
Example #2
0
 public bool TransferFundsForTransaction(Transaction t)
 {
     using (SqlConnection conn = new SqlConnection(connStr))
     {
         conn.Open();
         if (conn.Execute("ModifyCustomerAccountsForTransaction", new { DebitCustomerID = t.DebitCustomerID, CreditCustomerID = t.CreditCustomerID, Amount = t.Amount }, commandType: CommandType.StoredProcedure) > 0)
             return true;
         else
             return false;
     }
 }
        private DynamicParameters TransToDynParm(Transaction t)
        {
            DynamicParameters p = new DynamicParameters();

            p.Add("@TransactionBatchID", t.TransactionBatchID, DbType.String, ParameterDirection.Input);
            p.Add("@DebitCustomerID", t.DebitCustomerID, DbType.Int64, ParameterDirection.Input);
            p.Add("@CreditCustomerID", t.CreditCustomerID, DbType.Int64, ParameterDirection.Input);
            p.Add("@Type", (int)t.Type, DbType.Int32, ParameterDirection.Input);
            p.Add("@Amount", t.Amount, DbType.Decimal, ParameterDirection.Input);
            p.Add("@Reason", (int)t.Reason, DbType.Int32, ParameterDirection.Input);
            p.Add("@Source", (int)t.Source, DbType.Int32, ParameterDirection.Input);
            p.Add("@AgentID", t.AgentID, DbType.Int64, ParameterDirection.Input);
            p.Add("@Comment", t.Comment, DbType.String, ParameterDirection.Input);
            p.Add("@State", (int)t.State, DbType.Int32, ParameterDirection.Input);
            p.Add("@ForeignTransactionID", t.ForeignTransactionID, DbType.String, ParameterDirection.Input);
            p.Add("@BillingProcessorType", t.BillingProcessorType, DbType.Int32, ParameterDirection.Input);

            return p;
        }
        /*
         * Billing for a completed challenge:
         *
         *      For each bidder on the Challenge:
         *          Do they have the Actual Bid Amount in their Account Balance?
         *              yes:
         *                  create a transaction record: debit bidder, credit victor: Net Bid Amount
         *                  set transaction to status: Accepted
         *                  set transaction to source: FundedFromBalance
         *                  post the transaction
         *
         *              no:
         *                  attempt to add funds from the billing processor: Total Bid Amount
         *                  did the funding add succeed?
         *                      yes:
         *                          create a transaction record: debit bidder, credit victor: Net Bid Amount
         *                          create a transaction record: debit bidder, credit Fees Collected: Fees Amount
         *                          set both transactions' billing processor foreign transaction ID
         *                          set both transactions to status: Accepted
         *                          set both transactions to source: FundedByBillingProcessor
         *                          post transactions in batch
         *
         *                      no:
         *                          create a transaction record: debit bidder, credit victor: Net Bid Amount
         *                          create a transaction record: debit bidder, credit Fees Collected: Fees Amount
         *
         *                          set both transactions to status: ProcessorDeclined
         *                          post transactions in batch
         *
         *      Did all of the transactions go through?
         *          yes:
         *              set the ChallengeStatus State to Paid
         *              set the Challenge State to Paid
         *          no:
         *              set the ChallengeStatus State to PartialPaid
         *              set the Challenge State to PartialPaid
         * */
        private void PerformBillingForCompletedChallenge(long ChallengeID, long CustomerID)
        {
            List<ChallengeBid> bids = RepoFactory.GetChallengeBidRepo().Get(ChallengeID);
            IAccountRepository accountRepo=RepoFactory.GetAccountRepo();
            ITransactionRepository transRepo=RepoFactory.GetTransactionRepo();
            ChallengeStatus chalStatus=RepoFactory.GetChallengeStatusRepo().Get(CustomerID, ChallengeID);

            long feesAccountID = 0;

            int bidsPaid = 0;

            if (chalStatus.Status != (int)ChallengeStatus.StatusCodes.Completed)
            {
                System.Diagnostics.Trace.WriteLine("BILLING: Cust" + CustomerID.ToString() + "_Chal" + ChallengeID.ToString() + " - Caught a non-completed challenge status attempting to be billed");
                return;
            }

            foreach (ChallengeBid b in bids)
            {
                Customer cust=RepoFactory.GetCustomerRepo().GetWithID(b.CustomerID);

                decimal custBalance = accountRepo.BalanceForCustomerAccount(b.CustomerID);
                if (custBalance >= b.Amount)
                {
                    Transaction t = new Transaction() { Amount=(b.Amount - b.ComputedFees),
                                                        DebitCustomerID=b.CustomerID,
                                                        CreditCustomerID=chalStatus.CustomerID,
                                                        State=TransactionState.PendingInternalTransfer,
                                                        Source=TransactionSource.FundedFromBalance,
                                                        Reason=TransactionReason.CustomerAwardedBounty
                                                      };

                    if (accountRepo.TransferFundsForTransaction(t))
                    {
                        t.State = TransactionState.Successful;
                        bidsPaid++;
                    }

                    transRepo.RecordTransaction(t);
                }
                else
                {
                    Transaction netBountyTransaction = new Transaction()
                    {
                        Amount=(b.Amount-b.ComputedFees),
                        DebitCustomerID=b.CustomerID,
                        CreditCustomerID=chalStatus.CustomerID,
                        State=TransactionState.PendingFunds,
                        Source=TransactionSource.FundedFromBillingProcessor,
                        Reason=TransactionReason.CustomerAwardedBounty
                    };

                    Transaction feesTransaction = new Transaction()
                    {
                        Amount=b.ComputedFees,
                        DebitCustomerID=b.CustomerID,
                        CreditCustomerID=feesAccountID,
                        State=TransactionState.PendingFunds,
                        Source=TransactionSource.FundedFromBillingProcessor,
                        Reason=TransactionReason.CustomerAddedFunds
                    };

                    IBillingProcessor billingProcessor = BillingProcessorFactory.GetBillingProcessor((BillingProcessorFactory.SupportedBillingProcessor)cust.BillingType);

                    BillingProcessorResult chargeResult = billingProcessor.Charge(cust.BillingID, b.Amount);

                    netBountyTransaction.ForeignTransactionID = chargeResult.ForeignTransactionID;
                    feesTransaction.ForeignTransactionID = chargeResult.ForeignTransactionID;

                    if (chargeResult.Result == BillingProcessorResult.BillingProcessorResultCode.Paid)
                    {
                        // we got the money!! BOOYAH. stick it in their account.
                        // TODO: We should make sure this succeeds or we could see negative account balances.
                        accountRepo.ModifyCustomerAccountBalance(cust.ID, b.Amount);

                        netBountyTransaction.State = TransactionState.PendingInternalTransfer;
                        feesTransaction.State = TransactionState.PendingInternalTransfer;

                        // attempt the funds transfer.
                        // if we move the money successfully, update the transaction state.
                        if (accountRepo.TransferFundsForTransaction(netBountyTransaction))
                            netBountyTransaction.State = TransactionState.Successful;

                        if (accountRepo.TransferFundsForTransaction(feesTransaction))
                            feesTransaction.State = TransactionState.Successful;

                        if(netBountyTransaction.State==TransactionState.Successful && feesTransaction.State==TransactionState.Successful)
                            bidsPaid++; //only if the entire thing was successful
                    }
                    else
                    {
                        // we no get the money.
                        netBountyTransaction.State = TransactionState.ProcessorDecline;
                        feesTransaction.State = TransactionState.ProcessorDecline;

                        // since they don't have the money, don't perform any transfers.
                    }

                    List<Transaction> transBatch = new List<Transaction>(2);
                    transBatch.Add(netBountyTransaction);
                    transBatch.Add(feesTransaction);

                    // TODO: This transaction ID might not be unique if we have to keep retrying this batch.
                    transRepo.RecordTransactionBatch(transBatch, "Chal"+chalStatus.ChallengeID+"+Cust"+chalStatus.CustomerID+"+"+System.DateTime.Now.Ticks.ToString());
                }
            }

            if (bidsPaid >= bids.Count)
                chalStatus.Status = (int)ChallengeStatus.StatusCodes.Paid;
            else if (bidsPaid < bids.Count)
                chalStatus.Status = (int)ChallengeStatus.StatusCodes.PartialPaid;

            RepoFactory.GetChallengeStatusRepo().Update(chalStatus); // plz work
        }
 public bool RecordTransaction(Transaction t)
 {
     return false;
 }
Example #6
0
 public bool TransferFundsForTransaction(Transaction t)
 {
     return (context.ModifyCustomerAccountsForTransaction(t.DebitAccountID, t.CreditAccountID, t.Amount) != 0);
 }