private CheckEventChain SetChainProperties(ICollection <Chain> ChainCollection, Chain Chain) { var eventChain = new CheckEventChain() { CurrentEvent = GetEventEntity(Chain.Id.Value), PassEvent = GetEventEntity(Chain.SuccessEvent), FailEvent = GetEventEntity(Chain.FailEvent) }; eventChain.PassEventNotFound = Chain.SuccessEvent.HasValue && eventChain.PassEvent == null; eventChain.FailEventNotFound = Chain.FailEvent.HasValue && eventChain.FailEvent == null; eventChain.CurrentEventIsStart = Chain.IsStart; var references = ChainCollection.Where(x => x.SuccessEvent == Chain.Id.Value || x.FailEvent == Chain.Id.Value).Select(x => x.Id.Value); eventChain.CurrentEventReferences = new List <int>(); eventChain.CurrentEventReferences.AddRange(references); return(eventChain); }
/// <summary> /// Validate a Chain object depending on its type. It will also check its success/fail events if any. /// </summary> /// <param name="chainEvent">This object contains the current event and its success/fail events if any plus any /// references to the current object.</param> /// <returns></returns> private async Task <bool> Validate(CheckEventChain chainEvent) { var eventDto = _mapper.Map <EventEntity>(chainEvent.CurrentEvent); if (eventDto == null || chainEvent.PassEventNotFound || chainEvent.FailEventNotFound) { AddErrorToCollection(new Error { Key = "Bad Event Reference", Message = "An event referenced in your Chain does not exist for this game." }); return(false); } var type = eventDto.Type; var valid = true; // depending on the event type apply different rules if (type == EventType.Submission) { // then make sure its ok it should be set as a start event // it must have at least a pass round var hasPassEvent = chainEvent.PassEvent != null ? true : false; var hasFailEvent = chainEvent.FailEvent != null ? true : false; var passTimeCheck = false; var failTimeCheck = false; if (hasPassEvent) { // check start dates of pass or fail events are after the current eventdto. passTimeCheck = chainEvent.PassEvent.StartDate > eventDto.EndDate ? true : false; } if (hasFailEvent) { failTimeCheck = chainEvent.FailEvent.StartDate > eventDto.EndDate ? true : false; } if (hasPassEvent && (!passTimeCheck)) // if it has a pass event but has failed the time check. { valid = false; AddErrorToCollection(new Error { Key = "Event Id " + eventDto.Id, Message = "Event of type '" + eventDto.Type + "'. Clashes with event id " + chainEvent.PassEvent.Id + ". Please check times don't overlap." }); } if (hasFailEvent && (!failTimeCheck)) { valid = false; AddErrorToCollection(new Error { Key = "Event Id " + eventDto.Id, Message = "Event of type '" + eventDto.Type + "'. Clashes with event id " + chainEvent.FailEvent.Id + ". Please check times don't overlap." }); } if (chainEvent.CurrentEventReferences.Count > 0) { // iterate over references to this event to make sure dates dont collide. foreach (var id in chainEvent.CurrentEventReferences) { var eventEntity = GetEventEntity(id); // now check end dates dont clash with start dates. if (eventEntity.EndDate > eventDto.StartDate) { valid = false; AddErrorToCollection(new Error { Key = "Event Id " + eventDto.Id, Message = "Event of type '" + eventDto.Type + "'. Dates clashing with another event." }); } } } chainEvent.IsValid = valid; } else if (type == EventType.Moderate) { // it MUST sit inbetween two other events. if (chainEvent.CurrentEventReferences.Count > 0) { valid = true; } else { AddErrorToCollection(new Error { Key = "Event Id " + eventDto.Id, Message = "Event of type '" + eventDto.Type + "' must follow another event in the Chain." }); return(false); } if (chainEvent.CurrentEventIsStart) { AddErrorToCollection(new Error { Key = "Event Id " + eventDto.Id, Message = "Event of type '" + eventDto.Type + "' cannot start a Chain." }); return(false); } // so check other events that this event id is used in either a pass or fail event // MIGHT NOT NEED TO DO THIS AS I CHECK ALL OTHER PASS FAIL EVENTS SO IT SHOULD BE PICKED UP //foreach (var eventRef in ChainEvent.CurrentEventReferences) //{ // // this eventref MUST happen before the current one we are validating // var e = GetEventEntity(eventRef); // var timeCheck = false; // // check end dates of pass or fail events are BEFORE the current eventdto startdate // timeCheck = e.EndDate < eventDto.StartDate ? true : false; // valid = timeCheck; // if (!valid) // { // AddErrorToCollection(new Error // { // Key = "Event Id " + eventDto.Id, // Message = "Chain for event Id " + eventDto.Id + " type of " // + eventDto.Type + ". Dates clashing with another event." // }); // break; // } //} // it must have at least a pass round var hasPassEvent = chainEvent.PassEvent != null ? true : false; var hasFailEvent = chainEvent.FailEvent != null ? true : false; var passTimeCheck = false; var failTimeCheck = false; if (hasPassEvent) { // check start dates of pass or fail events are after the current eventdto. passTimeCheck = chainEvent.PassEvent.StartDate > eventDto.EndDate ? true : false; } if (hasFailEvent) { failTimeCheck = chainEvent.FailEvent.StartDate > eventDto.EndDate ? true : false; } if (hasPassEvent && passTimeCheck) { valid = true; } else { AddErrorToCollection(new Error { Key = "Event Id " + eventDto.Id, Message = "Chain for event Id " + eventDto.Id + " type of '" + eventDto.Type + "'. Must have a success event set and times must not clash." }); valid = false; } if (hasFailEvent && (!failTimeCheck)) { AddErrorToCollection(new Error { Key = "Event Id " + eventDto.Id, Message = "Event of type '" + eventDto.Type + "'. Clashes with event id " + chainEvent.FailEvent.Id + ". Please check times don't overlap." }); valid = false; } chainEvent.IsValid = valid; } else if (type == EventType.Custom) { // cannot start a chain if (chainEvent.CurrentEventIsStart) { AddErrorToCollection(new Error { Key = "Event Id " + eventDto.Id, Message = "Event of type '" + eventDto.Type + "' cannot start a Chain." }); return(false); } return(true); } else if (type == EventType.RandomDraw) { // it MUST have a previous event. if (chainEvent.CurrentEventReferences.Count > 0) { valid = true; } else { AddErrorToCollection(new Error { Key = "Event Id " + eventDto.Id, Message = "Event of type '" + eventDto.Type + "' must follow another event in the Chain." }); } if (chainEvent.CurrentEventIsStart) { AddErrorToCollection(new Error { Key = "Event Id " + eventDto.Id, Message = "Event of type '" + eventDto.Type + "' cannot start a Chain." }); return(false); } // so check other events that this event id is used in either a pass or fail event // MIGHT NOT NEED TO DO THIS AS I CHECK ALL OTHER PASS FAIL EVENTS SO IT SHOULD BE PICKED UP //foreach (var eventRef in ChainEvent.CurrentEventReferences) //{ // // this eventref MUST happen before the current one we are validating // var e = GetEventEntity(eventRef); // var timeCheck = false; // // check end dates of pass or fail events are BEFORE the current eventdto startdate // timeCheck = e.EndDate < eventDto.StartDate ? true : false; // valid = timeCheck; // if (!valid) // { // AddErrorToCollection(new Error // { // Key = "Event Id " + eventDto.Id, // Message = "Chain for event Id " + eventDto.Id + " type of " // + eventDto.Type + ". Dates clashing with another event." // }); // break; // } //} // check any pass or fail events that times dont collide. var hasPassEvent = chainEvent.PassEvent != null ? true : false; var hasFailEvent = chainEvent.FailEvent != null ? true : false; var passTimeCheck = false; var failTimeCheck = false; if (hasPassEvent) { // check start dates of pass or fail events are after the current eventdto. passTimeCheck = chainEvent.PassEvent.StartDate > eventDto.EndDate ? true : false; } else { // IT MUST HAVE A PASS EVENT TO PASS THE WINNERS ONTO. AddErrorToCollection(new Error { Key = "Event Id " + eventDto.Id, Message = "Event of type '" + eventDto.Type + "'. It must have a success event to pass eventual winners onto." }); valid = false; } if (hasFailEvent) { failTimeCheck = chainEvent.FailEvent.StartDate > eventDto.EndDate ? true : false; } // FAIL THE TIME CHECKS IF THEY COLLIDE WITH THIS CURRENT EVENT. if (hasPassEvent && (!passTimeCheck)) { AddErrorToCollection(new Error { Key = "Event Id " + eventDto.Id, Message = "Event of type '" + eventDto.Type + "'. Clashes with event id " + chainEvent.PassEvent.Id + ". Please check times don't overlap." }); valid = false; } if (hasFailEvent && (!failTimeCheck)) { AddErrorToCollection(new Error { Key = "Event Id " + eventDto.Id, Message = "Event of type '" + eventDto.Type + "'. Clashes with event id " + chainEvent.FailEvent.Id + ". Please check times don't overlap." }); valid = false; } chainEvent.IsValid = valid; } return(valid); }