Example #1
0
        /// <summary>
        /// Reset the negotiation to a "in negotiation" state.
        /// </summary>
        /// <param name="consumerTrustNegotiations">The the negotiations to reset.</param>
        internal static void Reject(ConsumerTrustNegotiationInfo[] consumerTrustNegotiations)
        {
            // An instance of the shared data model is required to use its methods.
            DataModel dataModel = new DataModel();

            // The business logic requires the current time and the user identifier for auditing.
            Guid     createUserId   = TradingSupport.UserId;
            DateTime createDateTime = DateTime.UtcNow;
            DateTime modifiedTime   = createDateTime;
            Guid     modifiedUserId = createUserId;


            // This Web Method comes with an implicit transaction that is linked to its execution.
            DataModelTransaction dataModelTransaction = DataModelTransaction.Current;

            // This method can handle a batch of updates in a single transaction.
            foreach (ConsumerTrustNegotiationInfo consumerTrustNegotiationInfo in consumerTrustNegotiations)
            {
                List <ConsumerTrustNegotiationPaymentMethodTypeInfo> counterItems = new List <ConsumerTrustNegotiationPaymentMethodTypeInfo>();

                // The blotter is not passed in from the client but is used
                Guid   blotterId = Guid.Empty;
                Status negotiationStatus;
                TrustNegotiationInfo trustNegotiationInfo = null;
                // This is the next negotiation in the batch to be updated.
                ConsumerTrustNegotiationRow consumerTrustNegotiationRow =
                    DataModel.ConsumerTrustNegotiation.ConsumerTrustNegotiationKey.Find(consumerTrustNegotiationInfo.ConsumerTrustNegotiationId);

                try
                {
                    // Lock the current negotation record for reading.  The data model doesn't support reader lock promotion, so the programming model is to
                    // lock the database, collect the data, release the locks and then write.  This model is especially important when iterating through a
                    // large batch to prevent the number of locks from growing to large.
                    consumerTrustNegotiationRow.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);

                    // The blotter identifier is used for access control and is not passed in by the client.
                    blotterId            = consumerTrustNegotiationRow.BlotterId;
                    negotiationStatus    = StatusMap.FromId(consumerTrustNegotiationRow.StatusId);
                    trustNegotiationInfo = new TrustNegotiationInfo(consumerTrustNegotiationRow);

                    // Determine whether the client has the right to modify this record.
                    if (!TradingSupport.HasAccess(dataModelTransaction, blotterId, AccessRight.Write))
                    {
                        throw new FaultException <FluidTrade.Core.SecurityFault>(new SecurityFault("You do not have write access to the selected object."));
                    }

                    // The payment methods are maintained as a vector associated with the negotiation record.  This will lock each of the records and read the
                    // payment methods into a data structure so the locks don't need to be held when it is time to write
                    foreach (var consumerTrustNegotiationOfferPaymentMethodRow
                             in consumerTrustNegotiationRow.GetConsumerTrustNegotiationCounterPaymentMethodRows())
                    {
                        try
                        {
                            // Temporarily lock the record containing the payment method.
                            consumerTrustNegotiationOfferPaymentMethodRow.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);


                            // This list is used to delete the payment methods that are no longer part of this negotiation.
                            counterItems.Add(
                                new ConsumerTrustNegotiationPaymentMethodTypeInfo(
                                    consumerTrustNegotiationOfferPaymentMethodRow.PaymentMethodTypeId,
                                    consumerTrustNegotiationOfferPaymentMethodRow.ConsumerTrustNegotiationCounterPaymentMethodId,
                                    consumerTrustNegotiationOfferPaymentMethodRow.RowVersion));
                        }
                        finally
                        {
                            // At this point the payment method isn't needed.
                            consumerTrustNegotiationOfferPaymentMethodRow.ReleaseReaderLock(dataModelTransaction.TransactionId);
                        }
                    }

                    MatchRow matchRow = DataModel.Match.MatchKey.Find(trustNegotiationInfo.MatchId);
                    try
                    {
                        matchRow.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                        trustNegotiationInfo.MatchRowVersion = matchRow.RowVersion;
                        trustNegotiationInfo.ContraMatchId   = matchRow.ContraMatchId;
                    }
                    finally
                    {
                        matchRow.ReleaseReaderLock(dataModelTransaction.TransactionId);
                    }

                    MatchRow contraMatchRow = DataModel.Match.MatchKey.Find(trustNegotiationInfo.ContraMatchId);
                    try
                    {
                        contraMatchRow.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                        trustNegotiationInfo.ContraMatchRowVersion = contraMatchRow.RowVersion;
                    }
                    finally
                    {
                        contraMatchRow.ReleaseReaderLock(dataModelTransaction.TransactionId);
                    }
                }
                finally
                {
                    // At this point, the negotiation record isn't needed.  It is critical to release the reader locks before attempting a write.
                    consumerTrustNegotiationRow.ReleaseReaderLock(dataModelTransaction.TransactionId);
                }


                // At this point, all the data for this operation has been collected and the CRUD operations can be invoked to finish the update.  Note that
                // the counter party information is not modified here, but is done through the Chinese wall.
                Guid newNegotiationId = Guid.NewGuid();
                dataModel.CreateConsumerTrustNegotiation(
                    trustNegotiationInfo.AccountBalance,
                    trustNegotiationInfo.BlotterId,
                    newNegotiationId,
                    trustNegotiationInfo.CounterPaymentLength,
                    trustNegotiationInfo.CounterPaymentStartDateLength,
                    trustNegotiationInfo.CounterPaymentStartDateUnitId,
                    trustNegotiationInfo.CounterSettlementUnitId,
                    trustNegotiationInfo.CounterSettlementValue,
                    createDateTime,
                    createUserId,
                    trustNegotiationInfo.CreditCardId,
                    trustNegotiationInfo.IsRead,
                    trustNegotiationInfo.IsReply,
                    trustNegotiationInfo.MatchId,
                    modifiedTime,
                    modifiedUserId,
                    consumerTrustNegotiationInfo.PaymentLength,
                    consumerTrustNegotiationInfo.PaymentStartDateLength,
                    consumerTrustNegotiationInfo.PaymentStartDateUnitId,
                    consumerTrustNegotiationInfo.SettlementUnitId,
                    consumerTrustNegotiationInfo.SettlementValue,
                    StatusMap.FromCode(Status.Rejected),
                    out trustNegotiationInfo.Version);

                // This will add the payment methods to the negotiation that are not already there.
                foreach (Guid paymentMethodTypeId in consumerTrustNegotiationInfo.PaymentMethodTypes)
                {
                    dataModel.CreateConsumerTrustNegotiationOfferPaymentMethod(
                        blotterId,
                        newNegotiationId,
                        Guid.NewGuid(),
                        paymentMethodTypeId);
                }

                foreach (ConsumerTrustNegotiationPaymentMethodTypeInfo consumerTrustNegotiationPaymentMethodTypeInfo in counterItems)
                {
                    dataModel.UpdateConsumerTrustNegotiationCounterPaymentMethod(
                        blotterId,
                        null,
                        new Object[] { consumerTrustNegotiationPaymentMethodTypeInfo.ConsumerTrustNegotiationOfferPaymentMethodId },
                        newNegotiationId,
                        consumerTrustNegotiationPaymentMethodTypeInfo.PaymentMethodInfoId,
                        consumerTrustNegotiationPaymentMethodTypeInfo.RowVersion);
                }

                //Reset the Match Status Id.  This is required so the match engine will redo the match.  The
                //match engine does not recalculate if it is not in the initial three stages of - Valid, Partial, ValidwithFunds
                dataModel.UpdateMatch(
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    new object[] { trustNegotiationInfo.MatchId },
                    trustNegotiationInfo.MatchRowVersion,
                    StatusMap.FromCode(Status.ValidMatch),
                    null);

                //Reset the Contra Match Status Id
                dataModel.UpdateMatch(
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    new object[] { trustNegotiationInfo.ContraMatchId },
                    trustNegotiationInfo.ContraMatchRowVersion,
                    StatusMap.FromCode(Status.ValidMatch),
                    null);
            }
        }
Example #2
0
        /// <summary>
        /// Update a Consumer Trust Negotiation Record.
        /// </summary>
        internal static void Update(ConsumerTrustNegotiationInfo[] consumerTrustNegotiations)
        {
            // An instance of the shared data model is required to use its methods.
            DataModel dataModel = new DataModel();

            // The business logic requires the current time and the user identifier for auditing.
            Guid     createUserId   = TradingSupport.UserId;
            DateTime createDateTime = DateTime.UtcNow;
            DateTime modifiedTime   = createDateTime;
            Guid     modifiedUserId = createUserId;

            // This Web Method comes with an implicit transaction that is linked to its execution.
            DataModelTransaction dataModelTransaction = DataModelTransaction.Current;

            // This method can handle a batch of updates in a single transaction.
            foreach (ConsumerTrustNegotiationInfo consumerTrustNegotiationInfo in consumerTrustNegotiations)
            {
                // The payment methods available to this negotiation is a vector.  Rather than delete everything and re-add it anytime an update is made, a
                // list of changes is constructed: new payment methods are added, obsolete payment methods are deleted and the ones that haven't changed are
                // left alone.  These list help to work out the differences.
                List <ConsumerTrustNegotiationPaymentMethodTypeInfo> counterItems = new List <ConsumerTrustNegotiationPaymentMethodTypeInfo>();

                // The blotter is not passed in from the client but is used
                Guid blotterId = Guid.Empty;
                TrustNegotiationInfo trustNegotiationInfo = null;
                // This is the next negotiation in the batch to be updated.
                ConsumerTrustNegotiationRow consumerTrustNegotiationRow =
                    DataModel.ConsumerTrustNegotiation.ConsumerTrustNegotiationKey.Find(consumerTrustNegotiationInfo.ConsumerTrustNegotiationId);

                Guid  matchId         = Guid.Empty;
                Int64 originalVersion = Int64.MinValue;
                // Lock the current negotation record for reading.  The data model doesn't support reader lock promotion, so the programming model is to
                // lock the database, collect the data, release the locks and then write.  This model is especially important when iterating through a
                // large batch to prevent the number of locks from growing to large.
                consumerTrustNegotiationRow.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                try
                {
                    matchId         = consumerTrustNegotiationRow.MatchId;
                    originalVersion = consumerTrustNegotiationRow.Version;
                }
                finally
                {
                    consumerTrustNegotiationRow.ReleaseReaderLock(dataModelTransaction.TransactionId);
                    consumerTrustNegotiationRow = null;
                }

                //Determine the most recent Negotiation to grab the counter payment methods.


                Int64    maxVersion = Int64.MinValue;
                MatchRow matchRow   = DataModel.Match.MatchKey.Find(matchId);
                matchRow.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                try
                {
                    foreach (ConsumerTrustNegotiationRow versionRow in matchRow.GetConsumerTrustNegotiationRows())
                    {
                        try
                        {
                            versionRow.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                            if (versionRow.Version > maxVersion)
                            {
                                maxVersion = versionRow.Version;
                                consumerTrustNegotiationRow = versionRow;
                            }
                        }
                        finally
                        {
                            versionRow.ReleaseReaderLock(dataModelTransaction.TransactionId);
                        }
                    }
                }
                finally
                {
                    matchRow.ReleaseReaderLock(dataModelTransaction.TransactionId);
                }


                consumerTrustNegotiationRow.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                try
                {
                    //Check for rowversion
                    if (originalVersion != consumerTrustNegotiationRow.Version)
                    {
                        throw new global::System.ServiceModel.FaultException <FluidTrade.Core.OptimisticConcurrencyFault>(
                                  new global::FluidTrade.Core.OptimisticConcurrencyFault("ConsumerTrustNegotiation",
                                                                                         new object[] { consumerTrustNegotiationInfo.ConsumerTrustNegotiationId }),
                                  new FaultReason("Negotiation is busy.  Please try again!"));
                    }


                    // The blotter identifier is used for access control and is not passed in by the client.
                    blotterId            = consumerTrustNegotiationRow.BlotterId;
                    trustNegotiationInfo = new TrustNegotiationInfo(consumerTrustNegotiationRow);

                    // Determine whether the client has the right to modify this record.
                    if (!TradingSupport.HasAccess(dataModelTransaction, blotterId, AccessRight.Write))
                    {
                        throw new FaultException <FluidTrade.Core.SecurityFault>(new SecurityFault("You do not have write access to the selected object."));
                    }

                    // The payment methods are maintained as a vector associated with the negotiation record.  This will lock each of the records and read the
                    // payment methods into a data structure so the locks don't need to be held when it is time to write
                    foreach (var consumerTrustNegotiationOfferPaymentMethodRow
                             in consumerTrustNegotiationRow.GetConsumerTrustNegotiationCounterPaymentMethodRows())
                    {
                        try
                        {
                            // Temporarily lock the record containing the payment method.
                            consumerTrustNegotiationOfferPaymentMethodRow.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);


                            // This list is used to delete the payment methods that are no longer part of this negotiation.
                            counterItems.Add(
                                new ConsumerTrustNegotiationPaymentMethodTypeInfo(
                                    consumerTrustNegotiationOfferPaymentMethodRow.PaymentMethodTypeId,
                                    consumerTrustNegotiationOfferPaymentMethodRow.ConsumerTrustNegotiationCounterPaymentMethodId,
                                    consumerTrustNegotiationOfferPaymentMethodRow.RowVersion));
                        }
                        finally
                        {
                            // At this point the payment method isn't needed.
                            consumerTrustNegotiationOfferPaymentMethodRow.ReleaseReaderLock(dataModelTransaction.TransactionId);
                        }
                    }
                }
                finally
                {
                    // At this point, the negotiation record isn't needed.  It is critical to release the reader locks before attempting a write.
                    consumerTrustNegotiationRow.ReleaseReaderLock(dataModelTransaction.TransactionId);
                }

                // At this point, all the data for this operation has been collected and the CRUD operations can be invoked to finish the update.  Note that
                // the counter party information is not modified here, but is done through the Chinese wall.
                Guid newNegotiationId = Guid.NewGuid();
                dataModel.CreateConsumerTrustNegotiation(
                    trustNegotiationInfo.AccountBalance,
                    trustNegotiationInfo.BlotterId,
                    newNegotiationId,
                    trustNegotiationInfo.CounterPaymentLength,
                    trustNegotiationInfo.CounterPaymentStartDateLength,
                    trustNegotiationInfo.CounterPaymentStartDateUnitId,
                    trustNegotiationInfo.CounterSettlementUnitId,
                    trustNegotiationInfo.CounterSettlementValue,
                    createDateTime,
                    createUserId,
                    trustNegotiationInfo.CreditCardId,
                    trustNegotiationInfo.IsRead,
                    trustNegotiationInfo.IsReply,
                    trustNegotiationInfo.MatchId,
                    modifiedTime,
                    modifiedUserId,
                    consumerTrustNegotiationInfo.PaymentLength,
                    consumerTrustNegotiationInfo.PaymentStartDateLength,
                    consumerTrustNegotiationInfo.PaymentStartDateUnitId,
                    consumerTrustNegotiationInfo.SettlementUnitId,
                    consumerTrustNegotiationInfo.SettlementValue,
                    consumerTrustNegotiationInfo.StatusId,
                    out trustNegotiationInfo.Version);

                // This will add the payment methods to the negotiation that are not already there.
                foreach (Guid paymentMethodTypeId in consumerTrustNegotiationInfo.PaymentMethodTypes)
                {
                    dataModel.CreateConsumerTrustNegotiationOfferPaymentMethod(
                        blotterId,
                        newNegotiationId,
                        Guid.NewGuid(),
                        paymentMethodTypeId);
                }

                //Since we cannot create new counter payments, we will update the existing ones.
                foreach (ConsumerTrustNegotiationPaymentMethodTypeInfo consumerTrustNegotiationPaymentMethodTypeInfo in counterItems)
                {
                    dataModel.UpdateConsumerTrustNegotiationCounterPaymentMethod(
                        blotterId,
                        null,
                        new Object[] { consumerTrustNegotiationPaymentMethodTypeInfo.ConsumerTrustNegotiationOfferPaymentMethodId },
                        newNegotiationId,
                        consumerTrustNegotiationPaymentMethodTypeInfo.PaymentMethodInfoId,
                        consumerTrustNegotiationPaymentMethodTypeInfo.RowVersion);
                }
            }
        }