/// <summary> /// Parses a given xml string that repressents a DCRGraph from DCRGraphs.net. /// Returns all the informaton needed to create a DCRGraph. /// </summary> /// <param name="xmlString"></param> /// <returns></returns> public EventAndRolesContainer Parse(string xmlString) { XDocument doc = XDocument.Parse(xmlString); //Workflow title string workflowTitle = ParseWorkflowTitle(doc); //Nodes EventAndRolesContainer container = ParseNodes(doc); //Constraints: container.Conditions = ParseConditionsReversed(doc); container.Responses = ParseResponses(doc); container.Exclusions = ParseExclusions(doc); container.Inclusions = ParseIncludes(doc); container.Milestones = ParseMilestonesReversed(doc); //List<string> RolesList = ParseRoles(doc); //Return data: return(container); }
/// <summary> /// Method to parse a DCRGraph from an xml file. It will read all the informaion and put into lists. /// </summary> /// <param name="doc"></param> /// <returns></returns> private EventAndRolesContainer ParseNodes(XDocument doc) { //Mapper constraints: var idOfIncludedEvents = (from includedEvent in doc.Descendants("included").Elements() select includedEvent.FirstAttribute.Value); //Think about checking for ID. var idOfPendingEvents = (from pendingEvent in doc.Descendants("pendingResponses").Elements() select pendingEvent.FirstAttribute.Value); //Think about checking for ID. var idOfExecutedEvents = (from executedEvent in doc.Descendants("executed").Elements() select executedEvent.FirstAttribute.Value); //Think about checking for ID. IEnumerable <XElement> events = doc.Descendants("event").Where(element => element.HasElements); //Only takes event elements in events! //Creating result list: EventAndRolesContainer Container = new EventAndRolesContainer(); //Creating and adding data to nodes: foreach (var _event in events) { DCREvent Event = new DCREvent(); //I create one NodeData for each _event //Assigning Id Event.EventId = _event.Attribute("id").Value; //Assigning Name: Event.Label = (from labelMapping in doc.Descendants("labelMapping") where labelMapping.Attribute("eventId").Value.Equals(Event.EventId) select labelMapping.Attribute("labelId").Value).FirstOrDefault(); //Assigning Roles: var roles = _event.Descendants("role"); foreach (var role in roles) { if (role.Value != "") { Container.Roles.Add(role.Value); Container.EventRoles.Add(new WebAPI.XMLParser.EventRole(role.Value, Event.EventId)); } } //Assigning Groups: var groups = _event.Descendants("group"); foreach (var group in groups) { if (group.Value != "") { Container.Groups.Add(group.Value); Container.EventGroups.Add(new WebAPI.XMLParser.EventGroup(group.Value, Event.EventId)); } } //Mark Included if (idOfIncludedEvents.Contains(Event.EventId)) { Event.Included = true; } //Mark Pending: if (idOfPendingEvents.Contains(Event.EventId)) { Event.Pending = true; } //Mark Executed: if (idOfExecutedEvents.Contains(Event.EventId)) { Event.Executed = true; } //Add Created Node to collection Container.Events.Add(Event); } return(Container); }
/// <summary> /// Method to parse a DCRGraph from an xml file. It will read all the informaion and put into lists. /// </summary> /// <param name="doc"></param> /// <returns></returns> private EventAndRolesContainer ParseNodes(XDocument doc) { //Mapper constraints: var idOfIncludedEvents = (from includedEvent in doc.Descendants("included").Elements() select includedEvent.FirstAttribute.Value); //Think about checking for ID. var idOfPendingEvents = (from pendingEvent in doc.Descendants("pendingResponses").Elements() select pendingEvent.FirstAttribute.Value); //Think about checking for ID. var idOfExecutedEvents = (from executedEvent in doc.Descendants("executed").Elements() select executedEvent.FirstAttribute.Value); //Think about checking for ID. IEnumerable<XElement> events = doc.Descendants("event").Where(element => element.HasElements); //Only takes event elements in events! //Creating result list: EventAndRolesContainer Container = new EventAndRolesContainer(); //Creating and adding data to nodes: foreach (var _event in events) { DCREvent Event = new DCREvent(); //I create one NodeData for each _event //Assigning Id Event.EventId = _event.Attribute("id").Value; //Assigning Name: Event.Label = (from labelMapping in doc.Descendants("labelMapping") where labelMapping.Attribute("eventId").Value.Equals(Event.EventId) select labelMapping.Attribute("labelId").Value).FirstOrDefault(); //Assigning Roles: var roles = _event.Descendants("role"); foreach (var role in roles) { if (role.Value != "") { Container.Roles.Add(role.Value); Container.EventRoles.Add(new WebAPI.XMLParser.EventRole(role.Value, Event.EventId)); } } //Assigning Groups: var groups = _event.Descendants("group"); foreach (var group in groups) { if (group.Value != "") { Container.Groups.Add(group.Value); Container.EventGroups.Add(new WebAPI.XMLParser.EventGroup(group.Value, Event.EventId)); } } //Mark Included if (idOfIncludedEvents.Contains(Event.EventId)) Event.Included = true; //Mark Pending: if (idOfPendingEvents.Contains(Event.EventId)) Event.Pending = true; //Mark Executed: if (idOfExecutedEvents.Contains(Event.EventId)) Event.Executed = true; //Add Created Node to collection Container.Events.Add(Event); } return Container; }
/// <summary> /// Method to create new orders in the database. /// It will create a new order with the information it receives and with the DCRGraph which is currently in the xml file which the API reads from. /// </summary> /// <param name="container"></param> /// <param name="orderInfo"></param> /// <returns></returns> public async Task<Tuple<string, HttpStatusCode>> CreateOrder(EventAndRolesContainer container, NewOrderInfo orderInfo) { using (var db = new WebAPI.Models.DBObjects.Database()) { try { //setup a new dcrgraph var graph = new DCRGraph { AcceptingState = false, Lock = false, LockTime = DateTime.Now, DCREvents = container.Events, }; //setup a new order var order = new Order() { DCRGraph = graph, OrderDate = orderInfo.OrderDate, Notes = orderInfo.Notes, Table = orderInfo.Table, OrderDetails = new List<OrderDetail>(), OrderType = orderInfo.OrderType, RestaurantId = orderInfo.Restaurant }; //put items on the order. Can only put items that exists in the database on. foreach (var iq in orderInfo.ItemsAndQuantity) { var item = db.Items .FirstOrDefaultAsync(i => i.Name == iq.Key.Name).Result; if (!iq.Key.Name.ToLower().Equals(item.Name.ToLower())) { throw new Exception("Item '" + iq.Key.Name + "' did not exist in the database"); } order.OrderDetails.Add( new OrderDetail() { ItemId = item.Id, Item = item, Order = order, Quantity = iq.Value }); } //Determine if there should be a customer on the order. We do not want cutstomers with the phone number 0. if(orderInfo.Customer.Phone != 0) { //see if we already have customer with the same phone number, otherwise create a new one. var customer = await db.Customers .FirstOrDefaultAsync(c => c.Phone == orderInfo.Customer.Phone) ?? new Customer { City = orderInfo.Customer.City ?? "n/a", Email = orderInfo.Customer.Email ?? "n/a", FirstName = orderInfo.Customer.FirstAndMiddleNames ?? "n/a", LastName = orderInfo.Customer.LastName ?? "n/a", Phone = orderInfo.Customer.Phone, StreetAndNumber = orderInfo.Customer.StreetAndNumber ?? "n/a", Zipcode = orderInfo.Customer.ZipCode, Orders = new HashSet<Order> {order} }; order.Customer = customer; } db.Orders.Add(order); db.SaveChanges(); //put groups on events foreach (var i in container.EventGroups) { var group = db.Groups.FirstOrDefaultAsync(x => x.Name.Equals(i.GroupName)).Result; container.Events.Find(x => x.EventId.Equals(i.EventId)).Groups.Add(group); } //put roles on events foreach (var i in container.EventRoles) { var role = db.Roles.FirstOrDefaultAsync(x => x.Name.Equals(i.RoleName)).Result; container.Events.Find(x => x.EventId.Equals(i.EventId)).Roles.Add(role); } //put inclusions on events foreach (var i in container.Inclusions) { var fromEvent = container.Events.Find(x => x.EventId.Equals(i.fromNodeId)); var toEvent = container.Events.Find(x => x.EventId.Equals(i.toNodeId)); container.Events.Find(e => e.Id == fromEvent.Id).Includes.Add(toEvent); //InsertBySqlQuery(fromEvent.Id, toEvent.Id, "Includes"); } //put exclusions on events foreach (var i in container.Exclusions) { var fromEvent = container.Events.Find(x => x.EventId.Equals(i.fromNodeId)); var toEvent = container.Events.Find(x => x.EventId.Equals(i.toNodeId)); container.Events.Find(e => e.Id == fromEvent.Id).Excludes.Add(toEvent); //InsertBySqlQuery(fromEvent.Id, toEvent.Id, "Excludes"); } //put responses on events foreach (var i in container.Responses) { var fromEvent = container.Events.Find(x => x.EventId.Equals(i.fromNodeId)); var toEvent = container.Events.Find(x => x.EventId.Equals(i.toNodeId)); container.Events.Find(e => e.Id == fromEvent.Id).Responses.Add(toEvent); //InsertBySqlQuery(fromEvent.Id, toEvent.Id, "Milestones"); } //put conditions on events foreach (var i in container.Conditions) { var fromEvent = container.Events.Find(x => x.EventId.Equals(i.fromNodeId)); var toEvent = container.Events.Find(x => x.EventId.Equals(i.toNodeId)); container.Events.Find(e => e.Id == fromEvent.Id).Conditions.Add(toEvent); //InsertBySqlQuery(fromEvent.Id, toEvent.Id, "Conditions"); } //put milestones on events foreach (var i in container.Milestones) { var fromEvent = container.Events.Find(x => x.EventId.Equals(i.fromNodeId)); var toEvent = container.Events.Find(x => x.EventId.Equals(i.toNodeId)); container.Events.Find(e => e.Id == fromEvent.Id).Milestones.Add(toEvent); //InsertBySqlQuery(fromEvent.Id, toEvent.Id, "Milestones"); } foreach (var e in container.Events) { db.Entry(e).State = EntityState.Modified; } await db.SaveChangesAsync(); //needs statuscode exception handling DCREvent dcrEvent; switch (orderInfo.OrderType) { case "For serving": dcrEvent = order.DCRGraph.DCREvents.FirstOrDefault(e => e.Label == "Setup graph serving"); if (dcrEvent != null) { await new DbInteractions().ExecuteEvent(dcrEvent.Id, false); break; } return new Tuple<string, HttpStatusCode>("The DCRGraph does not contain the relvant setup event", HttpStatusCode.InternalServerError); case "For takeaway": dcrEvent = order.DCRGraph.DCREvents.FirstOrDefault(e => e.Label == "Setup graph takeaway"); if (dcrEvent != null) { await new DbInteractions().ExecuteEvent(dcrEvent.Id, false); break; } return new Tuple<string, HttpStatusCode>("The DCRGraph does not contain the relvant setup event", HttpStatusCode.InternalServerError); case "For delivery": dcrEvent = order.DCRGraph.DCREvents.FirstOrDefault(e => e.Label.Contains("Setup graph delivery")); if (dcrEvent != null) { await new DbInteractions().ExecuteEvent(dcrEvent.Id, false); break; } return new Tuple<string, HttpStatusCode>("The DCRGraph does not contain the relvant setup event", HttpStatusCode.InternalServerError); case "Bulk order": dcrEvent = order.DCRGraph.DCREvents.FirstOrDefault(e => e.Label.Contains("Setup bulk order")); if (dcrEvent != null) { await new DbInteractions().ExecuteEvent(dcrEvent.Id, false); break; } return new Tuple<string, HttpStatusCode>("The DCRGraph does not contain the relvant setup event", HttpStatusCode.InternalServerError); default: return new Tuple<string, HttpStatusCode>("ordertype id not match - " + orderInfo.OrderType, HttpStatusCode.InternalServerError); } //scope.Complete(); return new Tuple<string, HttpStatusCode>("success", HttpStatusCode.OK); } catch (Exception ex) { return new Tuple<string, HttpStatusCode>(ex.Message, HttpStatusCode.InternalServerError); } //} } }