/// <summary>
        /// Create a new Math record
        /// </summary>
        /// <returns></returns>
        public override Guid Create(Records.Match record)
        {
            DataModel dataModel = new DataModel();
            Guid      matchId   = Guid.NewGuid();

            DataModelTransaction dataModelTransaction = DataModelTransaction.Current;
            Guid blotter = record.BlotterId.GetValueOrDefault();

            if (blotter == Guid.Empty || !TradingSupport.HasAccess(dataModelTransaction, blotter, AccessRight.Write))
            {
                throw new SecurityException("Current user does not have write access to the selected blotter");
            }

            ////Create a match
            dataModel.CreateMatch(
                record.BlotterId.GetValueOrDefault(),
                record.ContraMatchId.GetValueOrDefault(),
                record.ContraOrderId.GetValueOrDefault(),
                record.HeatIndex,
                record.HeatIndexDetails,
                DateTime.UtcNow,
                matchId,
                record.StatusCodeId.GetValueOrDefault(),
                record.WorkingOrderId.GetValueOrDefault());

            return(matchId);
        }
        /// <summary>
        /// Update a match
        /// </summary>
        /// <returns></returns>
        public override void Update(Records.Match record)
        {
            DataModel dataModel = new DataModel();

            DataModelTransaction dataModelTransaction = DataModelTransaction.Current;
            Guid blotter = record.BlotterId.GetValueOrDefault();

            if (blotter == Guid.Empty || !TradingSupport.HasAccess(dataModelTransaction, blotter, AccessRight.Write))
            {
                throw new SecurityException("Current user does not have write access to the selected blotter");
            }

            if (record.RowId == null || DataModel.Match.MatchKey.Find(record.RowId) == null)
            {
                throw new FaultException <RecordNotFoundFault>(new RecordNotFoundFault("Match", new object[] { record.RowId }));
            }

            dataModel.UpdateMatch(
                record.BlotterId,
                record.ContraMatchId,
                record.ContraOrderId,
                record.HeatIndex,
                record.HeatIndexDetails,
                record.MatchedTime,
                null, new object[] { record.RowId },
                record.RowVersion,
                record.StatusCodeId,
                record.WorkingOrderId);
        }
Exemple #3
0
        /// <summary>
        /// Update Negotiation record
        /// </summary>
        /// <param name="record"></param>
        public override void Update(FluidTrade.Guardian.Records.Negotiation record)
        {
            DataModel dataModel = new DataModel();

            DataModelTransaction dataModelTransaction = DataModelTransaction.Current;
            Guid blotter = record.BlotterId.GetValueOrDefault();

            if (blotter == Guid.Empty || !TradingSupport.HasAccess(dataModelTransaction, blotter, AccessRight.Write))
            {
                throw new SecurityException("Current user does not have write access to the selected blotter");
            }

            if (record.RowId == null || DataModel.Negotiation.NegotiationKey.Find(record.RowId) == null)
            {
                throw new FaultException <RecordNotFoundFault>(new RecordNotFoundFault("Negotiation", new object[] { record.RowId }));
            }

            dataModel.UpdateNegotiation(
                record.BlotterId,
                record.ExecutionId,
                record.IsRead,
                record.MatchId,
                null,
                new object[] { record.RowId },
                record.Quantity,
                record.RowVersion,
                record.StatusCodeId);
        }
Exemple #4
0
        /// <summary>
        /// Create Negotiation record
        /// </summary>
        /// <param name="record"></param>
        /// <returns></returns>
        public override Guid Create(FluidTrade.Guardian.Records.Negotiation record)
        {
            DataModel dataModel     = new DataModel();
            Guid      negotiationId = Guid.NewGuid();

            DataModelTransaction dataModelTransaction = DataModelTransaction.Current;
            Guid blotter = record.BlotterId.GetValueOrDefault();

            if (blotter == Guid.Empty || !TradingSupport.HasAccess(dataModelTransaction, blotter, AccessRight.Write))
            {
                throw new SecurityException("Current user does not have write access to the selected blotter");
            }

            ////Create a negotiation
            dataModel.CreateNegotiation(
                blotter,
                record.ExecutionId.GetValueOrDefault(),
                record.IsRead,
                record.MatchId.GetValueOrDefault(),
                negotiationId,
                record.Quantity,
                record.StatusCodeId.GetValueOrDefault());

            return(negotiationId);
        }
Exemple #5
0
        /// <summary>Inserts a Order record.</summary>
        /// <param name="transaction">Commits or rejects a set of commands as a unit</param>
        /// <param name="blockOrderId">The value for the BlockOrderId column.</param>
        /// <param name="accountId">The value for the AccountId column.</param>
        /// <param name="securityId">The value for the SecurityId column.</param>
        /// <param name="settlementId">The value for the SettlementId column.</param>
        /// <param name="brokerId">The value for the BrokerId column.</param>
        /// <param name="transactionTypeCode">The value for the TransactionTypeCode column.</param>
        /// <param name="timeInForceCode">The value for the TimeInForceCode column.</param>
        /// <param name="orderTypeCode">The value for the OrderTypeCode column.</param>
        /// <param name="conditionCode">The value for the ConditionCode column.</param>
        /// <param name="rowVersion">The value for the RowVersion column.</param>
        /// <param name="isAgency">The value for the Agency column.</param>
        /// <param name="quantity">The value for the Quantity column.</param>
        /// <param name="price1">The value for the Price1 column.</param>
        /// <param name="price2">The value for the Price2 column.</param>
        /// <param name="note">The value for the Note column.</param>
        /// <param name="createdTime">The value for the CreatedTime column.</param>
        /// <param name="createdLoginId">The value for the CreatedLoginId column.</param>
        /// <param name="modifiedTime">The value for the ModifiedTime column.</param>
        /// <param name="modifiedLoginId">The value for the ModifiedLoginId column.</param>
        public static int Insert(
            Transaction transaction,
            object blockOrderId,
            object blotterId,
            int accountId,
            int securityId,
            int settlementId,
            object brokerId,
            int transactionTypeCode,
            int timeInForceCode,
            int orderTypeCode,
            object conditionCode,
            ref long rowVersion,
            object isAgency,
            System.Decimal quantity,
            object price1,
            object price2,
            object note)
        {
            // The rowVersion of the block order is declared here, but it is not passed back to the caller.
            long rowVersionBlockOrder = long.MinValue;

            // This will find a block order for the order, or create a block order if one is needed.  The order must be associated
            // with a block at all times.
            if (blockOrderId == null)
            {
                // If the blotter wasn't provided, then find a blotter using the mapping of securities to blotters.
                if (blotterId == null)
                {
                    ServerMarketData.SecurityRow securityRow = ServerMarketData.Security.FindBySecurityId(securityId);
                    if (securityRow == null)
                    {
                        throw new Exception(string.Format("Security {0} does not exist", securityId));
                    }
                    blotterId = TradingSupport.AutoRoute(securityRow, quantity);
                }

                // If the order hasn't been associated with a block order yet, then find open one up.  The 'Open' method will
                // either return a block that matches the attributes of the order -- and can still be blocked -- or it will create
                // a new block based on the attributes of this new order.
                blockOrderId = Shadows.WebService.Trading.BlockOrder.Open(transaction, (int)blotterId, accountId, securityId,
                                                                          settlementId, brokerId, transactionTypeCode, timeInForceCode, orderTypeCode, conditionCode,
                                                                          ref rowVersionBlockOrder, isAgency, price1, price2);
            }

            // These values are provided by the server.
            int      positionTypeCode = Shadows.Quasar.Common.TransactionType.GetPosition(transactionTypeCode);
            DateTime createdTime      = DateTime.Now;
            int      createdLoginId   = ServerMarketData.LoginId;

            // Call the internal method to add the order.
            return(Shadows.WebService.Core.Order.Insert(transaction, (int)blockOrderId, accountId, securityId, settlementId, brokerId,
                                                        positionTypeCode, transactionTypeCode, timeInForceCode, orderTypeCode, conditionCode, ref rowVersion, null, null,
                                                        quantity, price1, price2, note, createdTime, createdLoginId, createdTime, createdLoginId));
        }
        /// <summary>
        /// Update WorkingOderRow
        /// </summary>
        public override void Update(WorkingOrderRecord record)
        {
            DataModel            dataModel            = new DataModel();
            DataModelTransaction dataModelTransaction = DataModelTransaction.Current;

            Guid blotter = record.BlotterId.GetValueOrDefault();

            if (blotter == Guid.Empty || !TradingSupport.HasAccess(dataModelTransaction, blotter, AccessRight.Write))
            {
                throw new SecurityException("Current user does not have write access to the selected blotter");
            }

            if (record.RowId == null || DataModel.WorkingOrder.WorkingOrderKey.Find(record.RowId) == null)
            {
                throw new FaultException <RecordNotFoundFault>(new RecordNotFoundFault("Working Order", new object[] { record.RowId }));
            }

            // It is a good idea to have a central method for updating the Working Order in the event the parameter order changes.
            dataModel.UpdateWorkingOrder(
                record.AutomaticQuantity,
                record.BlotterId,
                null,
                null,
                record.CrossingCode,
                record.DestinationId,
                record.ExternalId0,
                record.IsAutomatic,
                record.IsAwake,
                record.IsBrokerMatch,
                record.IsHedgeFundMatch,
                record.IsInstitutionMatch,
                record.LimitPrice,
                DateTime.UtcNow,
                TradingSupport.UserId,
                record.OrderTypeCode,
                record.RowVersion,
                record.SecurityId,
                record.SettlementDate,
                record.SettlementId,
                record.SideId,
                record.StartUTCTime,
                record.StatusCodeId,
                record.StopPrice,
                record.StopUTCTime,
                record.SubmittedQuantity,
                record.SubmittedUTCTime,
                record.TimeInForceId,
                record.TradeDate,
                record.UploadedUTCTime,
                null,
                new object[] { record.RowId });
        }
        /// <summary>
        /// Create a new DebtHolder
        /// </summary>
        /// <returns></returns>
        public override Guid Create(WorkingOrderRecord record)
        {
            DataModel dataModel      = new DataModel();
            Guid      workingOrderId = Guid.NewGuid();

            DataModelTransaction dataModelTransaction = DataModelTransaction.Current;

            Guid blotter = record.BlotterId.GetValueOrDefault();

            if (blotter == Guid.Empty || !TradingSupport.HasAccess(dataModelTransaction, blotter, AccessRight.Write))
            {
                throw new SecurityException("Current user does not have write access to the selected blotter");
            }

            Guid     createdbyUserId = TradingSupport.UserId;
            DateTime currentUTCTime  = DateTime.UtcNow;

            ////Create a entry in credit card
            dataModel.CreateWorkingOrder(
                record.AutomaticQuantity,
                record.BlotterId.GetValueOrDefault(),
                currentUTCTime,
                createdbyUserId,
                record.CrossingCode.GetValueOrDefault(),
                record.DestinationId,
                record.ExternalId0,
                record.IsAutomatic,
                record.IsAwake,
                record.IsBrokerMatch,
                record.IsHedgeFundMatch,
                record.IsInstitutionMatch,
                record.LimitPrice,
                currentUTCTime,
                createdbyUserId,
                record.OrderTypeCode,
                record.SecurityId.GetValueOrDefault(),
                record.SettlementDate.GetValueOrDefault(currentUTCTime),
                record.SettlementId,
                record.SideId.GetValueOrDefault(),
                record.StartUTCTime,
                record.StatusCodeId.GetValueOrDefault(),
                record.StopPrice,
                record.StopUTCTime,
                record.SubmittedQuantity,
                record.SubmittedUTCTime,
                record.TimeInForceId.GetValueOrDefault(),
                record.TradeDate.GetValueOrDefault(currentUTCTime),
                record.UploadedUTCTime,
                workingOrderId);

            return(workingOrderId);
        }
Exemple #8
0
        /// <summary>
        /// Delete a debt holder
        /// </summary>
        /// <returns>True for sucess</returns>
        public override ErrorCode Delete(Entity record)
        {
            DataModel            dataModel            = new DataModel();
            DataModelTransaction dataModelTransaction = DataModelTransaction.Current;

            if (!TradingSupport.HasAccess(dataModelTransaction, record.RowId, AccessRight.FullControl))
            {
                throw new SecurityException("Current user does not have write access to the selected Entity");
            }

            if (record.RowId == null || DataModel.Entity.EntityKey.Find(record.RowId) == null)
            {
                return(ErrorCode.RecordNotFound);
            }

            dataModel.DestroyEntity(
                new object[] { record.RowId },
                record.RowVersion);

            return(ErrorCode.Success);
        }
        /// <summary>
        /// Delete a match
        /// </summary>
        /// <returns>True for sucess</returns>
        public override ErrorCode Delete(Records.Match record)
        {
            if (record.RowId == null || DataModel.Match.MatchKey.Find(record.RowId) == null)
            {
                return(ErrorCode.RecordNotFound);
            }

            DataModel            dataModel            = new DataModel();
            MatchRow             matchRow             = DataModel.Match.MatchKey.Find(record.RowId);
            DataModelTransaction dataModelTransaction = DataModelTransaction.Current;

            matchRow.AcquireReaderLock(dataModelTransaction);
            if (!TradingSupport.HasAccess(dataModelTransaction, matchRow.BlotterId, AccessRight.FullControl))
            {
                return(ErrorCode.AccessDenied);
            }
            MatchRow contraMatchRow = DataModel.Match.MatchKey.Find(matchRow.ContraMatchId);

            matchRow.ReleaseReaderLock(dataModelTransaction.TransactionId);

            dataModel.DestroyMatch(
                new object[] { record.RowId },
                record.RowVersion);
            matchRow.ReleaseWriterLock(dataModelTransaction.TransactionId);

            // Delete the contra second, in case the record.RowVersion is off.
            if (contraMatchRow != null)
            {
                contraMatchRow.AcquireWriterLock(dataModelTransaction);
                dataModel.DestroyMatch(
                    new object[] { contraMatchRow.MatchId },
                    contraMatchRow.RowVersion);
                contraMatchRow.ReleaseWriterLock(dataModelTransaction.TransactionId);
            }

            return(ErrorCode.Success);
        }
Exemple #10
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);
            }
        }
Exemple #11
0
        /// <summary>
        /// Updates the state of a collection of Trust Negotiation settlement records.
        /// </summary>
        internal static void Update(ConsumerTrustNegotiationIsReadInfo[] consumerTrustNegotiationIsReads)
        {
            // An instance of the shared data model is required to use its methods.
            DataModel dataModel = new DataModel();

            // 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 (ConsumerTrustNegotiationIsReadInfo consumerTrustNegotiationIsReadInfo in consumerTrustNegotiationIsReads)
            {
                try
                {
                    if (consumerTrustNegotiationIsReadInfo != null && consumerTrustNegotiationIsReadInfo.ConsumerTrustNegotiationId != Guid.Empty)
                    {
                        // The blotter is not passed in from the client but is used to validate the users access to this record.
                        Guid  blotterId  = Guid.Empty;
                        Int64 version    = 0;
                        Int64 rowVersion = 0;

                        // This is the next negotiation in the batch to be updated.
                        ConsumerTrustNegotiationRow consumerTrustNegotiationRow =
                            DataModel.ConsumerTrustNegotiation.ConsumerTrustNegotiationKey.Find(consumerTrustNegotiationIsReadInfo.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;
                            version   = consumerTrustNegotiationRow.Version;
                            //Use the current rowversion to update.  This is to avoid an concurrency error. The client may not have
                            //gotten the updated row if they made a change before the IsRead fired of.  Since this is a benign change
                            //we can safely update the row and let the change trickle back on update.
                            rowVersion = consumerTrustNegotiationRow.RowVersion;

                            if (rowVersion != consumerTrustNegotiationIsReadInfo.RowVersion)
                            {
                                EventLog.Warning("ConsumerTrustNegotiaion ISRead incompatible rowVersions. Expected {0}, Got {1}. Using {0}",
                                                 consumerTrustNegotiationIsReadInfo.RowVersion, rowVersion);
                            }

                            // Determine whether the client has the right to modify this record.
                            if (!TradingSupport.HasAccess(dataModelTransaction, blotterId, AccessRight.Read))
                            {
                                throw new FaultException <FluidTrade.Core.SecurityFault>(new SecurityFault("You do not have read access to the selected object."));
                            }
                        }
                        finally
                        {
                            // At this point, the negotiation record isn't needed.  It is critical to release the reader locks before attempting a write.
                            if (consumerTrustNegotiationRow != null)
                            {
                                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.
                        dataModel.UpdateConsumerTrustNegotiation(
                            null,
                            null,
                            null,
                            new object[] { consumerTrustNegotiationIsReadInfo.ConsumerTrustNegotiationId },
                            null,
                            null,
                            null,
                            null,
                            null,
                            null,
                            null,
                            null,
                            consumerTrustNegotiationIsReadInfo.IsRead,
                            false,
                            null,
                            null,
                            null,
                            null,
                            null,
                            null,
                            null,
                            null,
                            rowVersion,
                            null,
                            version);
                    }
                }
                catch (FaultException <FluidTrade.Core.SecurityFault> faultException)
                {
                    //Throw this back to the client because we cannot handle this
                    throw faultException;
                }
                catch (Exception ex)
                {
                    //We will log the exception and try to carry on.
                    EventLog.Error(ex);
                }
            }
        }
Exemple #12
0
        private static void Update(RemoteBatch remoteBatch, RemoteTransaction remoteTransaction,
                                   ClientMarketData.ProposedOrderRow parentProposedOrder, decimal quantityInstruction)
        {
            // These define the assembly and the types within those assemblies that will be used to create the proposed orders on
            // the middle tier.
            RemoteAssembly remoteAssembly    = remoteBatch.Assemblies.Add("Service.Core");
            RemoteType     proposedOrderType = remoteAssembly.Types.Add("Shadows.WebService.Core.ProposedOrder");

            ClientMarketData.AccountRow  accountRow  = parentProposedOrder.AccountRow;
            ClientMarketData.SecurityRow securityRow = parentProposedOrder.SecurityRowByFKSecurityProposedOrderSecurityId;

            // This will turn the signed quantity into an absolute quantity and a transaction code (e.g. -1000 is turned into a
            // SELL of 1000 shares).
            decimal parentQuantity = Math.Abs(quantityInstruction);

            int parentTransactionTypeCode = TransactionType.Calculate(securityRow.SecurityTypeCode,
                                                                      parentProposedOrder.PositionTypeCode, quantityInstruction);

            // The time in force first comes from the user preferences, next, account settings and finally defaults to a day
            // orders.
            int timeInForceCode = !ClientPreferences.IsTimeInForceCodeNull() ? ClientPreferences.TimeInForceCode :
                                  !accountRow.IsTimeInForceCodeNull() ? accountRow.TimeInForceCode : TimeInForce.DAY;

            // The destination blotter comes first from the user preferences, second from the account preferences, and finally uses
            // the auto-routing logic.
            int blotterId = !ClientPreferences.IsBlotterIdNull() ? ClientPreferences.BlotterId :
                            !accountRow.IsBlotterIdNull() ? accountRow.BlotterId :
                            TradingSupport.AutoRoute(securityRow, parentQuantity);

            // Create a command to update the proposed order.
            RemoteMethod updateParent = proposedOrderType.Methods.Add("Update");

            updateParent.Transaction = remoteTransaction;
            updateParent.Parameters.Add("rowVersion", parentProposedOrder.RowVersion);
            updateParent.Parameters.Add("proposedOrderId", parentProposedOrder.ProposedOrderId);
            updateParent.Parameters.Add("accountId", parentProposedOrder.AccountId);
            updateParent.Parameters.Add("securityId", parentProposedOrder.SecurityId);
            updateParent.Parameters.Add("settlementId", parentProposedOrder.SettlementId);
            updateParent.Parameters.Add("blotterId", blotterId);
            updateParent.Parameters.Add("positionTypeCode", parentProposedOrder.PositionTypeCode);
            updateParent.Parameters.Add("transactionTypeCode", parentTransactionTypeCode);
            updateParent.Parameters.Add("timeInForceCode", timeInForceCode);
            updateParent.Parameters.Add("orderTypeCode", OrderType.Market);
            updateParent.Parameters.Add("quantity", parentQuantity);

            foreach (ClientMarketData.ProposedOrderTreeRow proposedOrderTree in
                     parentProposedOrder.GetProposedOrderTreeRowsByFKProposedOrderProposedOrderTreeParentId())
            {
                ClientMarketData.ProposedOrderRow childProposedOrder =
                    proposedOrderTree.ProposedOrderRowByFKProposedOrderProposedOrderTreeChildId;

                // If this is the settlement part of the order, then adjust the quantity.
                if (childProposedOrder.SecurityId == parentProposedOrder.SettlementId)
                {
                    // The settlement security is needed for the calculation of the cash impact of this trade.
                    ClientMarketData.CurrencyRow currencyRow =
                        MarketData.Currency.FindByCurrencyId(childProposedOrder.SettlementId);

                    decimal marketValue = parentQuantity * securityRow.QuantityFactor *
                                          Price.Security(currencyRow, securityRow) * securityRow.PriceFactor *
                                          TransactionType.GetCashSign(parentTransactionTypeCode);

                    decimal childQuantity = Math.Abs(marketValue);

                    int childTransactionTypeCode = TransactionType.Calculate(securityRow.SecurityTypeCode,
                                                                             parentProposedOrder.PositionTypeCode, marketValue);

                    // Create a command to update the proposed order.
                    RemoteMethod updateChild = proposedOrderType.Methods.Add("Update");
                    updateChild.Transaction = remoteTransaction;
                    updateChild.Parameters.Add("rowVersion", childProposedOrder.RowVersion);
                    updateChild.Parameters.Add("proposedOrderId", childProposedOrder.ProposedOrderId);
                    updateChild.Parameters.Add("accountId", childProposedOrder.AccountId);
                    updateChild.Parameters.Add("securityId", childProposedOrder.SecurityId);
                    updateChild.Parameters.Add("settlementId", childProposedOrder.SettlementId);
                    updateChild.Parameters.Add("blotterId", blotterId);
                    updateChild.Parameters.Add("positionTypeCode", parentProposedOrder.PositionTypeCode);
                    updateChild.Parameters.Add("transactionTypeCode", childTransactionTypeCode);
                    updateChild.Parameters.Add("timeInForceCode", timeInForceCode);
                    updateChild.Parameters.Add("orderTypeCode", OrderType.Market);
                    updateChild.Parameters.Add("quantity", childQuantity);
                }
            }
        }
        /// <summary>
        /// Create a new Debt Holder Record
        /// </summary>
        /// <returns></returns>
        internal Guid Create(EntityRow existingTrust, CreditCardRow existingCard)
        {
            DataModelTransaction dataModelTransaction = DataModelTransaction.Current;
            DataModel            dataModel            = new DataModel();
            Guid    tenantId = PersistenceHelper.GetTenantForEntity(dataModelTransaction, this.Record.Blotter);
            Guid    consumerId;
            Guid    entityId            = Guid.Empty;
            Guid    existingCardId      = Guid.Empty;
            Int64   existingCardVersion = 0;
            Boolean updateExistingCard  = false;

            if (existingTrust != null)
            {
                entityId = existingTrust.EntityId;
                existingTrust.ReleaseReaderLock(dataModelTransaction.TransactionId);
            }

            if (existingCard != null)
            {
                existingCard.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                existingCardId      = existingCard.CreditCardId;
                existingCardVersion = existingCard.RowVersion;
                if (TradingSupport.IsColumnOld(existingCard, "AccountBalance", this.Record.AccountBalance) ||
                    TradingSupport.IsColumnOld(existingCard, "AccountNumber", this.Record.AccountCode) ||
                    TradingSupport.IsColumnOld(existingCard, "DebtHolder", this.Record.DebtHolder) ||
                    TradingSupport.IsColumnOld(existingCard, "OriginalAccountNumber", this.Record.OriginalAccountNumber))
                {
                    updateExistingCard = true;
                }
            }

            // We need write access to the containing blotter in order to add a record to it.
            if (!TradingSupport.HasAccess(dataModelTransaction, this.Record.Blotter, AccessRight.Write))
            {
                throw new SecurityException("Current user does not have write access to the selected blotter");
            }
#if false
            if (existingTrust != null &&
                !TradingSupport.HasAccess(dataModelTransaction, entityId, AccessRight.Write))
            {
                throw new SecurityException("Current user does not have write access to the selected consumer");
            }
#endif
            if (existingTrust == null)
            {
                consumerId = this.CreateConsumer();
            }
            else
            {
                consumerId = this.UpdateConsumer(existingTrust);
            }

            if (existingCard == null)
            {
                dataModel.CreateCreditCard(
                    this.Record.AccountBalance,
                    this.Record.AccountCode,
                    consumerId,
                    Guid.NewGuid(),
                    this.Record.DebtHolder,
                    null,
                    null,
                    this.Record.AccountCode,
                    StringUtilities.CleanUpAlphaNumericString(this.Record.OriginalAccountNumber),
                    tenantId);
            }
            else if (updateExistingCard)
            {
                dataModel.UpdateCreditCard(
                    this.Record.AccountBalance,
                    this.Record.AccountCode,
                    null,
                    existingCardId,
                    new object[] { existingCardId },
                    this.Record.DebtHolder,
                    null,
                    null,
                    this.Record.AccountCode,
                    StringUtilities.CleanUpAlphaNumericString(this.Record.OriginalAccountNumber),
                    existingCardVersion,
                    null);
            }

            return(consumerId);
        }
        /// <summary>
        /// Create a new consumer.
        /// </summary>
        /// <returns>The ConsumerId of the consumer.</returns>
        private Guid CreateConsumer()
        {
            DataModel            dataModel            = new DataModel();
            DataModelTransaction dataModelTransaction = DataModelTransaction.Current;
            Guid       userId         = TradingSupport.UserId;
            Guid       tenantId       = PersistenceHelper.GetTenantForEntity(DataModelTransaction.Current, this.Record.Blotter);
            Guid       entityId       = Guid.NewGuid();
            Guid       consumerId     = Guid.NewGuid();
            Guid       creditCardId   = Guid.NewGuid();
            Guid       workingOrderId = Guid.NewGuid();
            CountryRow country;
            Guid       countryId;
            Guid?      provinceId = null;
            EntityRow  dollars;
            Guid       dollarsId;
            TypeRow    type;
            Guid       typeId;
            ImageRow   image;
            Guid       imageId;
            DateTime   currentUTCTime = DateTime.UtcNow;

            country = TradingSupport.FindCountryByKey(
                this.Record.ConfigurationId,
                "FK_Country_Security",
                new object[] { this.Record.CountryCode });
            countryId = country.CountryId;
            country.ReleaseReaderLock(dataModelTransaction.TransactionId);

            if (this.Record.ProvinceCode != null)
            {
                ProvinceRow province = TradingSupport.FindProvinceByKey(
                    this.Record.ConfigurationId,
                    "FK_Province_Consumer",
                    new object[] { this.Record.ProvinceCode });
                provinceId = province.ProvinceId;
                province.ReleaseReaderLock(dataModelTransaction.TransactionId);
            }

            dollars = TradingSupport.FindEntityByKey(
                this.Record.ConfigurationId,
                "FK_Security_WorkingOrder_SettlementId",
                new object[] { this.Record.Currency });
            dollarsId = dollars.EntityId;
            dollars.ReleaseReaderLock(dataModelTransaction.TransactionId);

            image = TradingSupport.FindImageByKey(
                this.Record.ConfigurationId,
                "FK_Image_Entity",
                new object[] { "OBJECT" });
            imageId = image.ImageId;
            image.ReleaseReaderLock(dataModelTransaction.TransactionId);

            type = TradingSupport.FindTypeByKey(
                this.Record.ConfigurationId,
                "FK_Type_Entity",
                new object[] { "CONSUMER TRUST" });
            typeId = type.TypeId;
            type.ReleaseReaderLock(dataModelTransaction.TransactionId);

            dataModel.CreateEntity(
                currentUTCTime,
                null,
                entityId,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                this.Record.CustomerCode,
                imageId,
                false,
                false,
                currentUTCTime,
                this.Record.SavingsEntityCode,
                tenantId,
                typeId);

            dataModel.CreateSecurity(
                null,
                countryId,
                null,
                null,
                null,
                1,
                1,
                entityId,
                this.Record.AccountCode,
                tenantId,
                VolumeCategoryMap.FromCode(VolumeCategory.Unknown));

            dataModel.CreateConsumer(
                this.Record.Address1,
                this.Record.Address2,
                this.Record.BankAccountNumber,
                this.Record.BankRoutingNumber,
                this.Record.City,
                consumerId,
                this.Record.DateOfBirth != null ? (object)this.Record.DateOfBirth.Value : null,
                null,
                null,
                this.Record.FirstName,
                this.Record.IsEmployed != null ? (object)this.Record.IsEmployed.Value : null,
                this.Record.LastName,
                this.Record.MiddleName,
                StringUtilities.CleanUpAlphaNumericString(this.Record.PhoneNumber),
                this.Record.PostalCode,
                provinceId,
                this.Record.Salutation,
                StringUtilities.CleanUpAlphaNumericString(this.Record.SocialSecurityNumber),
                this.Record.Suffix);
            dataModel.CreateConsumerTrust(
                consumerId,
                entityId,
                null,
                null,
                this.Record.SavingsAccount,
                this.Record.SavingsBalance,
                this.Record.Tag,
                tenantId,
                this.Record.VendorCode);

            //If this not found, there will be an exception. Let the exception propagate up.
            dataModel.CreateWorkingOrder(
                null,
                this.Record.Blotter,
                currentUTCTime,
                userId,
                CrossingMap.FromCode(Crossing.AlwaysMatch),
                null,
                null,
                null,
                null,
                true,
                true,
                true,
                null,
                DateTime.UtcNow,
                TradingSupport.UserId,
                OrderTypeMap.FromCode(OrderType.Market),
                entityId,
                DateTime.UtcNow,
                dollarsId,
                SideMap.FromCode(Side.Sell),
                DateTime.UtcNow,
                StatusMap.FromCode(Status.New),
                null,
                null,
                null,
                null,
                TimeInForceMap.FromCode(TimeInForce.GoodTillCancel),
                DateTime.UtcNow,
                DateTime.UtcNow,
                workingOrderId);

            // Create the access control record for this new entity.
            dataModel.CreateAccessControl(
                Guid.NewGuid(),
                AccessRightMap.FromCode(AccessRight.FullControl),
                entityId,
                userId,
                tenantId);

            return(consumerId);
        }
Exemple #15
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public override void Update(Entity record)
        {
            DataModel                      dataModel    = new DataModel();
            DataModelTransaction           transaction  = DataModelTransaction.Current;
            DateTime                       modifiedTime = DateTime.UtcNow;
            EntityRow                      entityRow    = DataModel.Entity.EntityKey.Find(record.RowId);
            Dictionary <String, EntityRow> parents      = new Dictionary <String, EntityRow>();
            List <String>                  parentNames  = new List <String>();

            EntityTreeRow[] entityTreeRows;
            String          oldName = null;
            Int64           rowVersion;

            if (!TradingSupport.HasAccess(transaction, record.RowId, AccessRight.Write))
            {
                throw new SecurityException("Current user does not have write access to the selected Entity");
            }
            if (record.Name != null && !EntityPersistence.IsNameValid(record.Name as String))
            {
                throw new FaultException <ArgumentFault>(new ArgumentFault("Names cannot contain a backslash"), "Names cannot contain a backslash");
            }

            entityRow.AcquireReaderLock(transaction);
            entityTreeRows = entityRow.GetEntityTreeRowsByFK_Entity_EntityTree_ChildId();
            oldName        = entityRow.Name;
            rowVersion     = entityRow.RowVersion;
            entityRow.ReleaseLock(transaction.TransactionId);

            if (!oldName.Equals(record.Name))
            {
                foreach (EntityTreeRow entityTreeRow in entityTreeRows)
                {
                    EntityRow parentEntityRow;

                    entityTreeRow.AcquireReaderLock(transaction);
                    parentEntityRow = entityTreeRow.EntityRowByFK_Entity_EntityTree_ParentId;
                    entityTreeRow.ReleaseLock(transaction.TransactionId);

                    parentEntityRow.AcquireReaderLock(transaction);
                    parents.Add(parentEntityRow.Name, parentEntityRow);
                    parentEntityRow.ReleaseLock(transaction.TransactionId);
                }

                parentNames = parents.Keys.ToList();

                parentNames.Sort();

                foreach (String parentName in parentNames)
                {
                    parents[parentName].AcquireWriterLock(transaction);
                }

                foreach (EntityRow parentEntityRow in parents.Values)
                {
                    if (!EntityPersistence.IsNameUnique(transaction, parentEntityRow, record.Name as String))
                    {
                        throw new FaultException <RecordExistsFault>(
                                  new RecordExistsFault("Entity", new object[] { record.Name }),
                                  "An entity with this name already exists");
                    }
                }
            }

            dataModel.UpdateEntity(
                null,
                record.Description,
                null,
                new object[] { record.RowId },
                record.ExternalId0,
                record.ExternalId1,
                record.ExternalId2,
                record.ExternalId3,
                record.ExternalId4,
                record.ExternalId5,
                record.ExternalId6,
                record.ExternalId7,
                record.ImageId,
                record.IsHidden,
                record.IsReadOnly,
                modifiedTime,
                record.Name,
                rowVersion,
                record.TenantId,
                null);
        }
        /// <summary>
        /// If a matching consumer debt record already exists, update the account with this, rather than creating a new one.
        /// </summary>
        /// <param name="entity">The entity row of the consumer debt record.</param>
        /// <returns>The entityId.</returns>
        internal Guid Update(EntityRow entity)
        {
            DataModel            dataModel            = new DataModel();
            DataModelTransaction dataModelTransaction = DataModelTransaction.Current;
            CountryRow           country;
            Guid            countryId;
            Guid?           provinceId = null;
            EntityRow       dollars;
            Guid            dollarsId;
            ConsumerRow     consumer;
            ConsumerDebtRow consumerDebt;
            CreditCardRow   creditCard;
            SecurityRow     security;
            WorkingOrderRow workingOrder;
            Guid            consumerId;
            Guid            consumerDebtId = entity.EntityId;
            Guid            creditCardId;
            Guid            entityId   = entity.EntityId;
            Guid            securityId = entity.EntityId;
            Guid            workingOrderId;
            Int64           consumerVersion;
            Int64           consumerDebtVersion;
            Int64           creditCardVersion;
            Int64           entityVersion = entity.RowVersion;
            Int64           securityVersion;
            Int64           workingOrderVersion;
            Boolean         updateConsumer     = false;
            Boolean         updateConsumerDebt = false;
            Boolean         updateCreditCard   = false;
            Boolean         updateEntity       = false;
            Boolean         updateSecurity     = false;
            DateTime        currentUTCTime     = DateTime.UtcNow;

            entity.ReleaseReaderLock(dataModelTransaction.TransactionId);

            // We need write access to the containing blotter in order to add a record to it.
            if (!DataModelFilters.HasAccess(dataModelTransaction, TradingSupport.UserId, this.Record.Blotter, AccessRight.Write))
            {
                throw new SecurityException("Current user does not have write access to the selected blotter");
            }
#if false
            // We need write access to the consumer debt's entity in order to update it.
            if (!TradingSupport.HasAccess(dataModelTransaction, entityId, AccessRight.Write))
            {
                throw new SecurityException("Current user does not have write access to the selected consumer debt");
            }
#endif
            // Via the country row...
            country = TradingSupport.FindCountryByKey(
                this.Record.ConfigurationId,
                "FK_Country_Security",
                new object[] { this.Record.CountryCode });
            countryId = country.CountryId;
            country.ReleaseReaderLock(dataModelTransaction.TransactionId);

            // ... get the province Id.
            if (this.Record.ProvinceCode != null)
            {
                ProvinceRow province = TradingSupport.FindProvinceByKey(
                    this.Record.ConfigurationId,
                    "FK_Province_Consumer",
                    new object[] { this.Record.ProvinceCode });
                provinceId = province.ProvinceId;
                province.ReleaseReaderLock(dataModelTransaction.TransactionId);
            }

            // Get the USD security Id.
            dollars = TradingSupport.FindEntityByKey(
                this.Record.ConfigurationId,
                "FK_Security_WorkingOrder_SettlementId",
                new object[] { this.Record.Currency });
            dollarsId = dollars.EntityId;
            dollars.ReleaseReaderLock(dataModelTransaction.TransactionId);

            // See if the entity needs to be updated.
            entity.AcquireReaderLock(dataModelTransaction);
            entityVersion = entity.RowVersion;
            if (TradingSupport.IsColumnOld(entity, "Name", this.Record.OriginalAccountNumber))
            {
                updateEntity = true;
            }
            entity.ReleaseLock(dataModelTransaction.TransactionId);


            // Get security's children see if we need to update securityRow.
            security = DataModel.Security.SecurityKey.Find(entityId);
            security.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
            securityVersion = security.RowVersion;
            consumerDebt    = DataModel.ConsumerDebt.ConsumerDebtKey.Find(security.SecurityId);
            workingOrder    = security.GetWorkingOrderRowsByFK_Security_WorkingOrder_SecurityId()[0];
            if (TradingSupport.IsColumnOld(security, "CountryId", countryId))
            {
                updateSecurity = true;
            }
            security.ReleaseLock(dataModelTransaction.TransactionId);

            // Control the working order:
            workingOrder.AcquireWriterLock(dataModelTransaction);

            // Get the consumer debt's children and see if we need to update the consumer debt.
            consumerDebt.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
            consumerDebtVersion = consumerDebt.RowVersion;
            creditCard          = DataModel.CreditCard.CreditCardKey.Find(consumerDebt.CreditCardId);
            if (TradingSupport.IsColumnOld(consumerDebt, "DateOfDelinquency", this.Record.DateOfDelinquency) ||
                TradingSupport.IsColumnOld(consumerDebt, "Representative", this.Record.Representative) ||
                TradingSupport.IsColumnOld(consumerDebt, "Tag", this.Record.Tag))
            {
                updateConsumerDebt = true;
            }
            consumerDebt.ReleaseLock(dataModelTransaction.TransactionId);

            creditCard.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
            creditCardId      = creditCard.CreditCardId;
            creditCardVersion = creditCard.RowVersion;
            consumer          = DataModel.Consumer.ConsumerKey.Find(creditCard.ConsumerId);
            if (TradingSupport.IsColumnOld(creditCard, "AccountBalance", this.Record.AccountBalance) ||
                TradingSupport.IsColumnOld(creditCard, "AccountNumber", this.Record.AccountCode) ||
                TradingSupport.IsColumnOld(creditCard, "DebtHolder", this.Record.DebtHolder) ||
                TradingSupport.IsColumnOld(creditCard, "OriginalAccountNumber", this.Record.OriginalAccountNumber))
            {
                updateCreditCard = true;
            }
            creditCard.ReleaseLock(dataModelTransaction.TransactionId);

            consumer.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
            consumerId      = consumer.ConsumerId;
            consumerVersion = consumer.RowVersion;
            if (TradingSupport.IsColumnOld(consumer, "Address1", this.Record.Address1) ||
                TradingSupport.IsColumnOld(consumer, "Address2", this.Record.Address2) ||
                TradingSupport.IsColumnOld(consumer, "City", this.Record.City) ||
                TradingSupport.IsColumnOld(consumer, "DateOfBirth", this.Record.DateOfBirth) ||
                TradingSupport.IsColumnOld(consumer, "FirstName", this.Record.FirstName) ||
                TradingSupport.IsColumnOld(consumer, "LastName", this.Record.LastName) ||
                TradingSupport.IsColumnOld(consumer, "PostalCode", this.Record.PostalCode) ||
                TradingSupport.IsColumnOld(consumer, "MiddleName", this.Record.MiddleName) ||
                TradingSupport.IsColumnOld(consumer, "PhoneNumber", this.Record.PhoneNumber) ||
                TradingSupport.IsColumnOld(consumer, "ProvinceId", provinceId) ||
                TradingSupport.IsColumnOld(consumer, "SocialSecurityNumber", this.Record.SocialSecurityNumber) ||
                TradingSupport.IsColumnOld(consumer, "Suffix", this.Record.Suffix))
            {
                updateConsumer = true;
            }
            consumer.ReleaseLock(dataModelTransaction.TransactionId);

            workingOrder.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
            workingOrderId      = workingOrder.WorkingOrderId;
            workingOrderVersion = workingOrder.RowVersion;

            //workingOrder.ReleaseLock(dataModelTransaction.TransactionId);

            // We need write access to the containing blotter in order to add a record to it.
            if (!TradingSupport.HasAccess(dataModelTransaction, PersistenceHelper.GetBlotterForConsumer(dataModelTransaction, consumerId), AccessRight.Write))
            {
                throw new SecurityException("Current user does not have write access to the original blotter");
            }

            if (updateConsumer)
            {
                dataModel.UpdateConsumer(
                    this.Record.Address1 != null ? (object)this.Record.Address1 : DBNull.Value,
                    this.Record.Address2 != null ? (object)this.Record.Address2 : DBNull.Value,
                    null,
                    null,
                    this.Record.City != null ? (object)this.Record.City : DBNull.Value,
                    consumerId,
                    new object[] { consumerId },
                    this.Record.DateOfBirth != null ? (object)this.Record.DateOfBirth.Value : DBNull.Value,
                    null,
                    null,
                    this.Record.FirstName != null ? (object)this.Record.FirstName : DBNull.Value,
                    null,
                    this.Record.LastName != null ? (object)this.Record.LastName : DBNull.Value,
                    this.Record.MiddleName != null ? (object)this.Record.MiddleName : DBNull.Value,
                    this.Record.PhoneNumber != null ? (object)StringUtilities.CleanUpAlphaNumericString(this.Record.PhoneNumber) : DBNull.Value,
                    this.Record.PostalCode != null ? (object)this.Record.PostalCode : DBNull.Value,
                    provinceId,
                    consumerVersion,
                    null,
                    StringUtilities.CleanUpAlphaNumericString(this.Record.SocialSecurityNumber),
                    this.Record.Suffix != null ? (object)this.Record.Suffix : DBNull.Value);
            }

            if (updateConsumerDebt)
            {
                dataModel.UpdateConsumerDebt(
                    null,
                    consumerDebtId,
                    new object[] { consumerDebtId },
                    null,
                    null,
                    this.Record.DateOfDelinquency != null ? (object)this.Record.DateOfDelinquency.Value : DBNull.Value,
                    null,
                    null,
                    this.Record.Representative != null ? (object)this.Record.Representative : DBNull.Value,
                    consumerDebtVersion,
                    this.Record.Tag != null ? (object)this.Record.Tag : DBNull.Value,
                    null,
                    null);
            }

            if (updateCreditCard)
            {
                dataModel.UpdateCreditCard(
                    this.Record.AccountBalance,
                    this.Record.AccountCode,
                    null,
                    creditCardId,
                    new object[] { creditCardId },
                    this.Record.DebtHolder,
                    null,
                    null,
                    null,
                    StringUtilities.CleanUpAlphaNumericString(this.Record.OriginalAccountNumber),
                    creditCardVersion,
                    null);
            }

            if (updateEntity)
            {
                dataModel.UpdateEntity(
                    null,
                    null,
                    entityId,
                    new object[] { entityId },
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    currentUTCTime,
                    this.Record.OriginalAccountNumber,
                    entityVersion,
                    null,
                    null);
            }

            if (updateSecurity)
            {
                dataModel.UpdateSecurity(
                    null,
                    countryId,
                    null,
                    null,
                    null,
                    1,
                    1,
                    securityVersion,
                    securityId,
                    new object[] { securityId },
                    null,
                    null,
                    null);
            }


            dataModel.UpdateWorkingOrder(
                null,
                this.Record.Blotter,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                currentUTCTime,
                TradingSupport.UserId,
                null,
                workingOrderVersion,
                null,
                null,
                dollarsId,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                currentUTCTime,
                workingOrderId,
                new object[] { workingOrderId });

            return(entityId);
        }
        /// <summary>
        /// Create a new Debt Holder Record
        /// </summary>
        /// <returns></returns>
        internal Guid Create()
        {
            DataModel            dataModel            = new DataModel();
            DataModelTransaction dataModelTransaction = DataModelTransaction.Current;
            Guid       userId   = TradingSupport.UserId;
            Guid       tenantId = PersistenceHelper.GetTenantForEntity(dataModelTransaction, this.Record.Blotter);
            Guid       entityId = Guid.Empty;
            Guid       consumerId;
            Guid       creditCardId;
            Guid       workingOrderId;
            CountryRow country;
            Guid       countryId;
            Guid?      provinceId = null;
            TypeRow    type;
            Guid       typeId;
            ImageRow   image;
            Guid       imageId;

            // These variables are used for auditing the changes to this record.
            DateTime  createdTime    = DateTime.UtcNow;
            Guid      createdUserId  = TradingSupport.UserId;
            DateTime  modifiedTime   = createdTime;
            Guid      modifiedUserId = createdUserId;
            EntityRow dollars;
            Guid      dollarsId;

            // We need write access to the containing blotter in order to add a record to it.
            if (!DataModelFilters.HasAccess(dataModelTransaction, userId, this.Record.Blotter, AccessRight.Write))
            {
                throw new SecurityException("Current user does not have write access to the selected blotter");
            }

            country = TradingSupport.FindCountryByKey(
                this.Record.ConfigurationId,
                "FK_Country_Security",
                new object[] { this.Record.CountryCode });
            countryId = country.CountryId;
            country.ReleaseReaderLock(dataModelTransaction.TransactionId);

            if (this.Record.ProvinceCode != null)
            {
                ProvinceRow province = TradingSupport.FindProvinceByKey(
                    this.Record.ConfigurationId,
                    "FK_Province_Consumer",
                    new object[] { this.Record.ProvinceCode });
                provinceId = province.ProvinceId;
                province.ReleaseReaderLock(dataModelTransaction.TransactionId);
            }

            dollars = TradingSupport.FindEntityByKey(
                this.Record.ConfigurationId,
                "FK_Security_WorkingOrder_SettlementId",
                new object[] { this.Record.Currency });
            dollarsId = dollars.EntityId;
            dollars.ReleaseReaderLock(dataModelTransaction.TransactionId);

            image = TradingSupport.FindImageByKey(
                this.Record.ConfigurationId,
                "FK_Image_Entity",
                new object[] { "OBJECT" });
            imageId = image.ImageId;
            image.ReleaseReaderLock(dataModelTransaction.TransactionId);

            type = TradingSupport.FindTypeByKey(
                this.Record.ConfigurationId,
                "FK_Type_Entity",
                new object[] { "CONSUMER DEBT" });
            typeId = type.TypeId;
            type.ReleaseReaderLock(dataModelTransaction.TransactionId);

            entityId       = Guid.NewGuid();
            consumerId     = Guid.NewGuid();
            creditCardId   = Guid.NewGuid();
            workingOrderId = Guid.NewGuid();

            dataModel.CreateEntity(
                createdTime,
                null,
                entityId,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                this.Record.AccountCode,
                imageId,
                false,
                false,
                modifiedTime,
                this.Record.OriginalAccountNumber,
                tenantId,
                typeId);

            dataModel.CreateSecurity(
                null,
                countryId,
                null,
                null,
                null,
                1,
                1,
                entityId,
                this.Record.AccountCode,
                tenantId,
                VolumeCategoryMap.FromCode(VolumeCategory.Unknown));

            dataModel.CreateConsumer(
                this.Record.Address1,
                this.Record.Address2,
                null,
                null,
                this.Record.City,
                consumerId,
                this.Record.DateOfBirth != null ? (object)this.Record.DateOfBirth.Value : null,
                null,
                null,
                this.Record.FirstName,
                null,
                this.Record.LastName,
                this.Record.MiddleName,
                StringUtilities.CleanUpAlphaNumericString(this.Record.PhoneNumber),
                this.Record.PostalCode,
                provinceId,
                null,
                StringUtilities.CleanUpAlphaNumericString(this.Record.SocialSecurityNumber),
                this.Record.Suffix);
            dataModel.CreateCreditCard(
                this.Record.AccountBalance,
                this.Record.AccountCode,
                consumerId,
                creditCardId,
                this.Record.DebtHolder,
                null,
                null,
                this.Record.AccountCode,
                StringUtilities.CleanUpAlphaNumericString(this.Record.OriginalAccountNumber),
                tenantId);
            dataModel.CreateConsumerDebt(
                this.Record.CollectionDate,
                entityId,
                consumerId,
                creditCardId,
                this.Record.DateOfDelinquency != null ? (object)this.Record.DateOfDelinquency.Value : null,
                null,
                null,
                this.Record.Representative,
                this.Record.Tag,
                tenantId,
                this.Record.VendorCode);

            dataModel.CreateWorkingOrder(
                null,
                this.Record.Blotter,
                createdTime,
                createdUserId,
                CrossingMap.FromCode(Crossing.AlwaysMatch),
                null,
                null,
                null,
                null,
                true,
                true,
                true,
                null,
                modifiedTime,
                modifiedUserId,
                OrderTypeMap.FromCode(OrderType.Market),
                entityId,
                createdTime,
                dollarsId,
                SideMap.FromCode(Side.Sell),
                createdTime,
                StatusMap.FromCode(Status.New),
                null,
                null,
                null,
                null,
                TimeInForceMap.FromCode(TimeInForce.GoodTillCancel),
                createdTime,
                createdTime,
                workingOrderId);

            // Create the access control record for this new entity.
            dataModel.CreateAccessControl(
                Guid.NewGuid(),
                AccessRightMap.FromCode(AccessRight.FullControl),
                entityId,
                userId,
                tenantId);

            return(entityId);
        }
        /// <summary>
        /// Update a consumer.
        /// </summary>
        /// <param name="entity">The ConsumerTrust's Entity row.</param>
        /// <returns>The ConsumerId of the Consumer row.</returns>
        private Guid UpdateConsumer(EntityRow entity)
        {
            DataModel            dataModel            = new DataModel();
            DataModelTransaction dataModelTransaction = DataModelTransaction.Current;
            DateTime             modified             = DateTime.UtcNow;
            CountryRow           country;
            Guid             countryId;
            Guid?            provinceId = null;
            EntityRow        dollars;
            Guid             dollarsId;
            ConsumerRow      consumer      = null;
            ConsumerTrustRow consumerTrust = null;
            SecurityRow      security      = null;
            WorkingOrderRow  workingOrder  = null;

            MatchRow[] matches;
            Guid       consumerId;
            Guid       consumerTrustId;
            Guid       entityId;
            Guid       securityId;
            Guid       workingOrderId;
            Int64      consumerVersion;
            Int64      consumerTrustVersion;
            Int64      entityVersion;
            Int64      securityVersion;
            Int64      workingOrderVersion;
            Boolean    updateConsumer      = false;
            Boolean    updateConsumerTrust = false;
            Boolean    updateEntity        = false;
            Boolean    updateSecurity      = false;

            country = TradingSupport.FindCountryByKey(
                this.Record.ConfigurationId,
                "FK_Country_Security",
                new object[] { this.Record.CountryCode });
            countryId = country.CountryId;
            country.ReleaseReaderLock(dataModelTransaction.TransactionId);

            if (this.Record.ProvinceCode != null)
            {
                ProvinceRow province = TradingSupport.FindProvinceByKey(
                    this.Record.ConfigurationId,
                    "FK_Province_Consumer",
                    new object[] { this.Record.ProvinceCode });
                provinceId = province.ProvinceId;
                province.ReleaseReaderLock(dataModelTransaction.TransactionId);
            }

            dollars = TradingSupport.FindEntityByKey(
                this.Record.ConfigurationId,
                "FK_Security_WorkingOrder_SettlementId",
                new object[] { this.Record.Currency });
            dollarsId = dollars.EntityId;
            dollars.ReleaseReaderLock(dataModelTransaction.TransactionId);

            try
            {
                entity.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                entityId      = entity.EntityId;
                entityVersion = entity.RowVersion;
                if (TradingSupport.IsColumnOld(entity, "Name", this.Record.OriginalAccountNumber))
                {
                    updateEntity = true;
                }
            }
            finally
            {
                entity.ReleaseLock(dataModelTransaction.TransactionId);
            }

            try
            {
                security = DataModel.Security.SecurityKey.Find(entityId);
                security.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                securityId      = entityId;
                securityVersion = security.RowVersion;
                workingOrder    = security.GetWorkingOrderRowsByFK_Security_WorkingOrder_SecurityId()[0];
                if (TradingSupport.IsColumnOld(security, "CountryId", countryId))
                {
                    updateSecurity = true;
                }
            }
            finally
            {
                security.ReleaseLock(dataModelTransaction.TransactionId);
            }


            // Control the working order:
            workingOrder.AcquireWriterLock(dataModelTransaction);

            try
            {
                consumerTrust = DataModel.ConsumerTrust.ConsumerTrustKey.Find(entityId);
                consumerTrust.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                consumerTrustId      = consumerTrust.ConsumerTrustId;
                consumerTrustVersion = consumerTrust.RowVersion;
                consumer             = DataModel.Consumer.ConsumerKey.Find(consumerTrust.ConsumerId);
                if (TradingSupport.IsColumnOld(consumerTrust, "SavingsAccount", this.Record.SavingsAccount) ||
                    TradingSupport.IsColumnOld(consumerTrust, "SavingsBalance", this.Record.SavingsBalance) ||
                    TradingSupport.IsColumnOld(consumerTrust, "Tag", this.Record.Tag))
                {
                    updateConsumerTrust = true;
                }
            }
            finally
            {
                consumerTrust.ReleaseLock(dataModelTransaction.TransactionId);
            }

            try
            {
                consumer.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                consumerId      = consumer.ConsumerId;
                consumerVersion = consumer.RowVersion;
                if (TradingSupport.IsColumnOld(consumer, "Address1", this.Record.Address1) ||
                    TradingSupport.IsColumnOld(consumer, "Address2", this.Record.Address2) ||
                    TradingSupport.IsColumnOld(consumer, "BankAccountNumber", this.Record.BankAccountNumber) ||
                    TradingSupport.IsColumnOld(consumer, "BankRoutingNumber", this.Record.BankRoutingNumber) ||
                    TradingSupport.IsColumnOld(consumer, "City", this.Record.City) ||
                    TradingSupport.IsColumnOld(consumer, "DateOfBirth", this.Record.DateOfBirth) ||
                    TradingSupport.IsColumnOld(consumer, "FirstName", this.Record.FirstName) ||
                    TradingSupport.IsColumnOld(consumer, "IsEmployed", this.Record.IsEmployed) ||
                    TradingSupport.IsColumnOld(consumer, "LastName", this.Record.LastName) ||
                    TradingSupport.IsColumnOld(consumer, "PostalCode", this.Record.PostalCode) ||
                    TradingSupport.IsColumnOld(consumer, "MiddleName", this.Record.MiddleName) ||
                    TradingSupport.IsColumnOld(consumer, "PhoneNumber", this.Record.PhoneNumber) ||
                    TradingSupport.IsColumnOld(consumer, "ProvinceId", provinceId) ||
                    TradingSupport.IsColumnOld(consumer, "SocialSecurityNumber", this.Record.SocialSecurityNumber) ||
                    TradingSupport.IsColumnOld(consumer, "Suffix", this.Record.Suffix))
                {
                    updateConsumer = true;
                }
            }
            finally
            {
                consumer.ReleaseLock(dataModelTransaction.TransactionId);
            }

            try
            {
                //workingOrder.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                workingOrderId      = workingOrder.WorkingOrderId;
                workingOrderVersion = workingOrder.RowVersion;
                matches             = workingOrder.GetMatchRows();
            }
            finally
            {
                //workingOrder.ReleaseLock(dataModelTransaction.TransactionId);
            }

            foreach (MatchRow match in matches)
            {
                if (WorkingOrderPersistence.IsSettled(dataModelTransaction, match))
                {
                    throw new FaultException <SecurityFault>(
                              new SecurityFault("Cannot update account that is settled")
                    {
                        FaultCode = ErrorCode.RecordExists
                    },
                              "Cannot update account that is settled");
                }
            }

            // We need write access to the containing blotter in order to add a record to it.
            if (!TradingSupport.HasAccess(dataModelTransaction, PersistenceHelper.GetBlotterForConsumer(dataModelTransaction, consumerId), AccessRight.Write))
            {
                throw new SecurityException("Current user does not have write access to the original blotter");
            }

            if (updateConsumer)
            {
                dataModel.UpdateConsumer(
                    this.Record.Address1 != null ? (object)this.Record.Address1 : DBNull.Value,
                    this.Record.Address2 != null ? (object)this.Record.Address2 : DBNull.Value,
                    this.Record.BankAccountNumber != null ? (object)this.Record.BankAccountNumber : DBNull.Value,
                    this.Record.BankRoutingNumber != null ? (object)this.Record.BankRoutingNumber : DBNull.Value,
                    this.Record.City != null ? (object)this.Record.City : DBNull.Value,
                    consumerId,
                    new object[] { consumerId },
                    this.Record.DateOfBirth != null ? (object)this.Record.DateOfBirth.Value : DBNull.Value,
                    null,
                    null,
                    this.Record.FirstName != null ? (object)this.Record.FirstName : DBNull.Value,
                    this.Record.IsEmployed != null ? (object)this.Record.IsEmployed.Value : DBNull.Value,
                    this.Record.LastName != null ? (object)this.Record.LastName : DBNull.Value,
                    this.Record.MiddleName != null ? (object)this.Record.MiddleName : DBNull.Value,
                    this.Record.PhoneNumber != null ? (object)StringUtilities.CleanUpAlphaNumericString(this.Record.PhoneNumber) : DBNull.Value,
                    this.Record.PostalCode != null ? (object)this.Record.PostalCode : DBNull.Value,
                    provinceId,
                    consumerVersion,
                    this.Record.Salutation,
                    StringUtilities.CleanUpAlphaNumericString(this.Record.SocialSecurityNumber),
                    this.Record.Suffix != null ? (object)this.Record.Suffix : DBNull.Value);
            }

            if (updateConsumerTrust)
            {
                dataModel.UpdateConsumerTrust(
                    null,
                    consumerTrustId,
                    new object[] { consumerTrustId },
                    null,
                    null,
                    consumerTrustVersion,
                    this.Record.SavingsAccount,
                    this.Record.SavingsBalance,
                    this.Record.Tag != null ? (object)this.Record.Tag : DBNull.Value,
                    null,
                    null);
            }

            if (updateEntity)
            {
                dataModel.UpdateEntity(
                    null,
                    null,
                    entityId,
                    new object[] { entityId },
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    modified,
                    this.Record.SavingsEntityCode,
                    entityVersion,
                    null,
                    null);
            }

            if (updateSecurity)
            {
                dataModel.UpdateSecurity(
                    null,
                    countryId,
                    null,
                    null,
                    null,
                    1,
                    1,
                    securityVersion,
                    securityId,
                    new object[] { securityId },
                    null,
                    null,
                    null);
            }

            dataModel.UpdateWorkingOrder(
                null,
                this.Record.Blotter,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                modified,
                TradingSupport.UserId,
                null,
                workingOrderVersion,
                null,
                null,
                dollarsId,
                null,
                null,
                StatusMap.FromCode(Status.New),
                null,
                null,
                null,
                null,
                null,
                null,
                modified,
                workingOrderId,
                new object[] { workingOrderId });

            return(consumerId);
        }
Exemple #19
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);
                }
            }
        }
        /// <summary>
        /// Delete a debt holder
        /// </summary>
        /// <returns>True for sucess</returns>
        public override ErrorCode Delete(ConsumerTrust record)
        {
            DataModel            dataModel   = new DataModel();
            DataModelTransaction transaction = DataModelTransaction.Current;

            if (record.RowId == null || DataModel.ConsumerTrust.ConsumerTrustKey.Find(record.RowId) == null)
            {
                return(ErrorCode.RecordNotFound);
            }

            ConsumerTrustRow consumerTrust = DataModel.ConsumerTrust.ConsumerTrustKey.Find(record.RowId);

            consumerTrust.AcquireReaderLock(transaction);
            Guid        debtId   = consumerTrust.ConsumerTrustId;
            ConsumerRow consumer = consumerTrust.ConsumerRow;
            DebtRuleRow debtRule = consumerTrust.DebtRuleRow;

            consumerTrust.ReleaseReaderLock(transaction.TransactionId);

#if false   // If we switch from explicitly deleting the working order to explicitly deleting the security, then we need this.
            if (!TradingSupport.HasAccess(transaction, debtId, AccessRight.Write))
            {
                return(ErrorCode.AccessDenied);
            }
#endif

            consumerTrust.AcquireWriterLock(transaction);
            if (consumerTrust.RowState != DataRowState.Deleted && consumerTrust.RowState != DataRowState.Detached)
            {
                dataModel.DestroyConsumerTrust(new object[] { consumerTrust.ConsumerTrustId }, record.RowVersion);
            }
            consumerTrust.ReleaseWriterLock(transaction.TransactionId);

            consumer.AcquireWriterLock(transaction);
            if (consumer.RowState != DataRowState.Deleted && consumer.RowState != DataRowState.Detached)
            {
                dataModel.DestroyConsumer(new object[] { consumer.ConsumerId }, consumer.RowVersion);
            }
            consumer.ReleaseWriterLock(transaction.TransactionId);

            if (debtRule != null)
            {
                debtRule.AcquireReaderLock(transaction);
                if (debtRule.RowState != DataRowState.Deleted && debtRule.RowState != DataRowState.Detached && debtRule.GetDebtRuleMapRows().Length == 0)
                {
                    DebtRulePersistence debtRulePersistence = new DebtRulePersistence();
                    Guid debtRuleId = debtRule.DebtRuleId;
                    long rowVersion = debtRule.RowVersion;
                    debtRule.ReleaseReaderLock(transaction.TransactionId);
                    debtRulePersistence.Delete(new Records.DebtRule {
                        RowId = debtRuleId, RowVersion = rowVersion
                    });
                }
                else
                {
                    debtRule.ReleaseReaderLock(transaction.TransactionId);
                }
            }

            return(ErrorCode.Success);
        }
Exemple #21
0
        /// <summary>
        /// Creates a command in a RemoteBatch structure to insert a proposed order.
        /// </summary>
        /// <param name="remoteBatch"></param>
        /// <param name="remoteTransaction"></param>
        /// <param name="accountRow"></param>
        /// <param name="securityRow"></param>
        /// <param name="positionTypeCode"></param>
        /// <param name="quantityInstruction"></param>
        private static void Insert(RemoteBatch remoteBatch, RemoteTransaction remoteTransaction,
                                   ClientMarketData.AccountRow accountRow, ClientMarketData.SecurityRow securityRow, int positionTypeCode,
                                   decimal quantityInstruction)
        {
            // These define the assembly and the types within those assemblies that will be used to create the proposed orders on
            // the middle tier.
            RemoteAssembly remoteAssembly        = remoteBatch.Assemblies.Add("Service.Core");
            RemoteType     proposedOrderType     = remoteAssembly.Types.Add("Shadows.WebService.Core.ProposedOrder");
            RemoteType     proposedOrderTreeType = remoteAssembly.Types.Add("Shadows.WebService.Core.ProposedOrderTree");

            // Find the default settlement for this order.
            int settlementId = Shadows.Quasar.Common.Security.GetDefaultSettlementId(securityRow);

            // As a convention between the rebalancing section and the order generation, the parentQuantity passed into this method
            // is a signed value where the negative values are treated as 'Sell' instructions and the positive values meaning
            // 'Buy'. This will adjust the parentQuantity so the trading methods can deal with an unsigned value, which is more
            // natural for trading.
            decimal parentQuantity = Math.Abs(quantityInstruction);

            // This will turn the signed parentQuantity into an absolute parentQuantity and a transaction code (e.g. -1000 is
            // turned into a SELL of 1000 shares).
            int parentTransactionTypeCode = TransactionType.Calculate(securityRow.SecurityTypeCode, positionTypeCode, quantityInstruction);

            // The time in force first comes from the user preferences, next, account settings and finally defaults to a day
            // orders.
            int timeInForceCode = !ClientPreferences.IsTimeInForceCodeNull() ?
                                  ClientPreferences.TimeInForceCode : !accountRow.IsTimeInForceCodeNull() ? accountRow.TimeInForceCode :
                                  TimeInForce.DAY;

            // The destination blotter comes first from the user preferences, second from the account preferences, and finally uses
            // the auto-routing logic.
            int parentBlotterId = ClientPreferences.IsBlotterIdNull() ? (accountRow.IsBlotterIdNull() ?
                                                                         TradingSupport.AutoRoute(securityRow, parentQuantity) : accountRow.BlotterId) : ClientPreferences.BlotterId;

            // Create a command to delete the relationship between the parent and child.
            RemoteMethod insertParent = proposedOrderType.Methods.Add("Insert");

            insertParent.Transaction = remoteTransaction;
            insertParent.Parameters.Add("proposedOrderId", DataType.Int, Direction.ReturnValue);
            insertParent.Parameters.Add("blotterId", parentBlotterId);
            insertParent.Parameters.Add("accountId", accountRow.AccountId);
            insertParent.Parameters.Add("securityId", securityRow.SecurityId);
            insertParent.Parameters.Add("settlementId", settlementId);
            insertParent.Parameters.Add("positionTypeCode", positionTypeCode);
            insertParent.Parameters.Add("transactionTypeCode", parentTransactionTypeCode);
            insertParent.Parameters.Add("timeInForceCode", timeInForceCode);
            insertParent.Parameters.Add("orderTypeCode", OrderType.Market);
            insertParent.Parameters.Add("quantity", parentQuantity);

            // Now it's time to create an order for the settlement currency.
            if (securityRow.SecurityTypeCode == SecurityType.Equity || securityRow.SecurityTypeCode == SecurityType.Debt)
            {
                // The underlying currency is needed for the market value calculations.
                ClientMarketData.CurrencyRow currencyRow = MarketData.Currency.FindByCurrencyId(settlementId);

                decimal marketValue = parentQuantity * securityRow.QuantityFactor * Price.Security(currencyRow, securityRow)
                                      * securityRow.PriceFactor * TransactionType.GetCashSign(parentTransactionTypeCode);

                // The stragegy for handling the settlement currency changes is to calculate the old market value, calculate the
                // new market value, and add the difference to the running total for the settlement currency of this security. The
                // new market value is the impact of the trade that was just entered.
                int childTransactionTypeCode = TransactionType.Calculate(securityRow.SecurityTypeCode, positionTypeCode,
                                                                         marketValue);
                decimal childQuantity = Math.Abs(marketValue);

                // The destination blotter comes first from the user preferences, second from the account preferences, and finally
                // uses the auto-routing logic.
                int childBlotterId = ClientPreferences.IsBlotterIdNull() ? (accountRow.IsBlotterIdNull() ?
                                                                            TradingSupport.AutoRoute(currencyRow.SecurityRow, childQuantity) : accountRow.BlotterId) :
                                     ClientPreferences.BlotterId;

                // Fill in the rest of the fields and the defaulted fields for this order. Create a command to delete the
                // relationship between the parent and child.
                RemoteMethod insertChild = proposedOrderType.Methods.Add("Insert");
                insertChild.Transaction = remoteTransaction;
                insertChild.Parameters.Add("proposedOrderId", DataType.Int, Direction.ReturnValue);
                insertChild.Parameters.Add("blotterId", childBlotterId);
                insertChild.Parameters.Add("accountId", accountRow.AccountId);
                insertChild.Parameters.Add("securityId", settlementId);
                insertChild.Parameters.Add("settlementId", settlementId);
                insertChild.Parameters.Add("transactionTypeCode", childTransactionTypeCode);
                insertChild.Parameters.Add("positionTypeCode", positionTypeCode);
                insertChild.Parameters.Add("timeInForceCode", timeInForceCode);
                insertChild.Parameters.Add("orderTypeCode", OrderType.Market);
                insertChild.Parameters.Add("quantity", childQuantity);

                RemoteMethod insertRelation = proposedOrderTreeType.Methods.Add("Insert");
                insertRelation.Transaction = remoteTransaction;
                insertRelation.Parameters.Add("parentId", insertParent.Parameters["proposedOrderId"]);
                insertRelation.Parameters.Add("childId", insertChild.Parameters["proposedOrderId"]);
            }
        }