Esempio n. 1
0
 /// <summary>
 /// Updates the status of the Destination Order.
 /// </summary>
 /// <param name="destinationOrderRow">The Working Order to be modified.</param>
 /// <param name="status">The new status of the Working Order.</param>
 private static void UpdateDestinationOrderStatus(DestinationOrderRow destinationOrderRow, Status status)
 {
     // It is a good idea to have a central method for updating the Destination Order in the event the parameter order changes.
     Execution.dataModel.UpdateDestinationOrder(null, null, null, null, null, null, null,
                                                new object[] { destinationOrderRow.DestinationOrderId }, null, null, null, null, null, null, null, null, null,
                                                destinationOrderRow.RowVersion, null, null, null, null, null, StatusMap.FromCode(status), null, null, null, null, null);
 }
Esempio n. 2
0
        /// <summary>
        /// Handler for validating Destination Order records.
        /// </summary>
        /// <param name="sender">The object that originated the event.</param>
        /// <param name="e">The event arguments.</param>
        internal static void OnDestinationOrderRowValidate(object sender, DestinationOrderRowChangeEventArgs e)
        {
            Int32   currentStatusCode;
            Decimal destinationOrderQuantity;
            DataModelTransaction dataModelTransaction;
            Int32           previousStatusCode;
            Decimal         sourceOrderQuantity;
            WorkingOrderRow workingOrderRow;

            // The Business Rules will be enforced on this Destination Order.  Note that it is locked at the point this handler is called.
            DestinationOrderRow destinationOrderRow = e.Row;

            // The action on the row determines which rule to evaluate.
            switch (destinationOrderRow.RowState)
            {
            case DataRowState.Added:

                // This rule will reject the operation if the Working Order is overcommitted with a destination.
                dataModelTransaction = DataModelTransaction.Current;

                // This rule will throw an exception if the quantity sent to a destination is greater than the quantity ordered.  The quantity ordered and
                // quantity sent can only be calcuated from the owning Working Order which must be locked in order to carry out the calculations.
                workingOrderRow = e.Row.WorkingOrderRow;
                workingOrderRow.AcquireReaderLock(dataModelTransaction);
                sourceOrderQuantity      = WorkingOrder.GetSourceOrderQuantity(dataModelTransaction, workingOrderRow);
                destinationOrderQuantity = WorkingOrder.GetDestinationOrderQuantity(dataModelTransaction, workingOrderRow);
                if (sourceOrderQuantity < destinationOrderQuantity)
                {
                    throw new FaultException <DestinationQuantityFault>(
                              new DestinationQuantityFault(workingOrderRow.WorkingOrderId, sourceOrderQuantity, destinationOrderQuantity));
                }

                break;

            case DataRowState.Modified:

                // Reject the operation if the Working Order is overcommitted with a destination.  Note that the order of the evaluation is important for
                // efficiency.  There is no need to sum up the source and Destination Orders if the quantity has been reduced as there's no chance it will be
                // over committed.
                Decimal originalQuantity = (Decimal)destinationOrderRow[DataModel.DestinationOrder.OrderedQuantityColumn, DataRowVersion.Original];
                Decimal currentQuantity  = (Decimal)destinationOrderRow[DataModel.DestinationOrder.OrderedQuantityColumn, DataRowVersion.Current];
                if (originalQuantity < currentQuantity)
                {
                    // Once it's determined that the order can be overcommitted, a middle tier context is required to lock the rows so the quantities can be
                    // aggregated.
                    dataModelTransaction = DataModelTransaction.Current;

                    // This rule will throw an exception if the quantity sent to a destination is greater than the quantity ordered.  The quantity ordered and
                    // quantity sent can only be calcuated from the owning Working Order which must be locked in order to carry out the calculations.
                    workingOrderRow = e.Row.WorkingOrderRow;
                    workingOrderRow.AcquireReaderLock(dataModelTransaction);
                    sourceOrderQuantity      = WorkingOrder.GetSourceOrderQuantity(dataModelTransaction, workingOrderRow);
                    destinationOrderQuantity = WorkingOrder.GetDestinationOrderQuantity(dataModelTransaction, workingOrderRow);
                    if (sourceOrderQuantity < destinationOrderQuantity)
                    {
                        throw new FaultException <DestinationQuantityFault>(
                                  new DestinationQuantityFault(workingOrderRow.WorkingOrderId, sourceOrderQuantity, destinationOrderQuantity));
                    }
                }

                // This rule will examine the effects of a state change of the Destination Order.  The stateChangeMatrix contains delegates to methods that
                // will determine what, if any, stats change should be applied to the Working Order due to the change in state of this Destination Order.
                previousStatusCode = Convert.ToInt32(StatusMap.FromId((Guid)destinationOrderRow[DataModel.DestinationOrder.StatusIdColumn, DataRowVersion.Original]));
                currentStatusCode  = Convert.ToInt32(StatusMap.FromId((Guid)destinationOrderRow[DataModel.DestinationOrder.StatusIdColumn, DataRowVersion.Current]));
                if (previousStatusCode != currentStatusCode)
                {
                    DestinationOrder.statusChangeMatrix[previousStatusCode, currentStatusCode](new Object[] { destinationOrderRow.WorkingOrderId });
                }

                break;

            case DataRowState.Deleted:

                // This rule will examine the effects of a state change of the Destination Order.  The stateChangeMatrix contains delegates to methods that
                // will determine what, if any, stats change should be applied to the Working Order due to the change in state of this Destination Order.
                previousStatusCode = Convert.ToInt32(StatusMap.FromId((Guid)destinationOrderRow[DataModel.DestinationOrder.StatusIdColumn, DataRowVersion.Original]));
                currentStatusCode  = (Int32)Status.Deleted;
                Guid workingOrderId = (Guid)destinationOrderRow[DataModel.DestinationOrder.WorkingOrderIdColumn, DataRowVersion.Original];
                DestinationOrder.statusChangeMatrix[previousStatusCode, currentStatusCode](new Object[] { workingOrderId });

                break;
            }
        }