public Guid OrderTicket(Contracts.Order newOrder, SeatIndex[] seats) { //1. validate the order is valid //validate newOrder.EventInfo and newOrder.CustomerInfo ICrmBase crmProx = null; IShowsService showsProx = null; IPricingService pricingProx = null; IReservationService reservationsProx = null; Guid reservationID; if (newOrder == null) throw new NullReferenceException(StringsResource.NullOrder); if (newOrder.CustomerInfo == null) throw new NullReferenceException(StringsResource.NullCustomer); if (newOrder.EventInfo == null) throw new NullReferenceException(StringsResource.NullEvent); if ((seats == null) || (seats.Count() == 0)) throw new ArgumentException(StringsResource.NoSeatsInOrder); #region Validate Customer //Contact the Crm service to ensure the customer exist. lock (this) { if (crmChf == null) crmChf = new ChannelFactory<ICrmBase>("CrmCertEP"); } try { crmProx = crmChf.CreateChannel(); var customer = crmProx.GetCustomerByID(newOrder.CustomerInfo.ID); if (customer == null) throw new TicketingException(string.Format(StringsResource.CustomerNotFound, newOrder.CustomerInfo.ID)); newOrder.CustomerInfo = CustomerMapper.MapToTicketingCustomer(customer); } catch (Exception ex) { LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message); throw new TicketingException(StringsResource.FailedToContactCrm, ex); } finally { var channel = crmProx as ICommunicationObject; if ((channel != null) && (channel.State == CommunicationState.Opened)) channel.Close(); } #endregion #region Validate Event ShowsService.Contracts.Event _event; //1. contact the shows service to fetch information about the event. lock (this) { if (showsChf == null) showsChf = new ChannelFactory<IShowsService>("ShowEP"); } try { showsProx = showsChf.CreateChannel(); _event = showsProx.FindEventByID(newOrder.EventInfo.EventID); if (_event == null) throw new TicketingException(string.Format(StringsResource.EventNotFound, newOrder.EventInfo.EventID)); newOrder.EventInfo = _event; } catch (Exception ex) { LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message); throw new TicketingException(StringsResource.FailedToContactShows + " " + ex.Message, ex); } finally { var channel = showsProx as ICommunicationObject; if ((channel != null) && (channel.State == CommunicationState.Opened)) channel.Close(); } //2. check the event exist and it is open if ((_event == null) || (_event.State != EventState.Opened)) throw new TicketingException(StringsResource.InvalidOrClosedEvent); #endregion #region Call Pricing to calculate the total price lock (this) { if (pricingChf == null) pricingChf = new ChannelFactory<IPricingService>("PricingEP"); } try { pricingProx = pricingChf.CreateChannel(); var price = pricingProx.CalculatePrice(reductionCode: newOrder.CustomerInfo.ReductionCode.Value, policyName: newOrder.EventInfo.PricingPolicy, listPrice: (int)newOrder.EventInfo.ListPrice, numberOfTickets: seats.Count(), currency: null); newOrder.TotalPrice = price * seats.Count(); } catch (Exception ex) { LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message); throw new TicketingException(StringsResource.FailedToContactPricing + " " + ex.Message, ex); } finally { var channel = pricingProx as ICommunicationObject; if ((channel != null) && (channel.State == CommunicationState.Opened)) channel.Close(); } #endregion #region Call the resrevation service and reserve seats //Contact the HallState service to perform the reservation. lock (this) { if (reservationsChf == null) reservationsChf = new ChannelFactory<IReservationService>("ReservationsEP"); } try { reservationsProx = reservationsChf.CreateChannel(); reservationID = reservationsProx.CreateResevation(new Reservation() { ID = Guid.NewGuid(), CustomerID = newOrder.CustomerInfo.ID, EventID = newOrder.EventInfo.EventID, Seats = seats.ToList(), Remarks = newOrder.Remarks }); } catch (Exception ex) { LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message); throw new TicketingException(StringsResource.FailedToContactHallState + " " + ex.Message, ex); } finally { var channel = reservationsProx as ICommunicationObject; if ((channel != null) && (channel.State == CommunicationState.Opened)) channel.Close(); } #endregion newOrder.ID = reservationID; newOrder.State = OrderState.Created; manager.OrderTicket(newOrder); #region ClientNotifications //ClientNotifications string userName = string.Empty; if ((OperationContext.Current != null) && (OperationContext.Current.ServiceSecurityContext != null) && (OperationContext.Current.ServiceSecurityContext.PrimaryIdentity != null)) userName = OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name; var clientRegistrations = MemoryRepository.Current.GetRegistrations(NotificationTypes.TicketingNotification, userName); if (clientRegistrations.Length > 0) ClientNotificationsManager.SendNotifications(new OrderMessage() { Content = "Order Created", OrderID = reservationID }, clientRegistrations); #endregion return newOrder.ID; }