public CompetitionsWorkflow(ICompetitionContext context, IDisciplineCalculatorManager calculatorManager, IDistanceDisciplineExpertManager distanceExpertManager,
                                    IEventRecorder recorder)
        {
            this.context               = context;
            this.calculatorManager     = calculatorManager;
            this.recorder              = recorder;
            this.distanceExpertManager = distanceExpertManager;

            DistancesWorkflow            = new DistancesWorkflow(context, calculatorManager, distanceExpertManager, recorder);
            DistanceCombinationsWorkflow = new DistanceCombinationsWorkflow(context, recorder);
            LicensesWorkflow             = new LicensesWorkflow(context, calculatorManager, recorder);
            RacesWorkflow = new RacesWorkflow(context, distanceExpertManager, recorder);
        }
        protected virtual void Dispose(bool disposing)
        {
            if (!isDisposed)
            {
                if (disposing)
                {
                    DistancesWorkflow.Dispose();
                    DistanceCombinationsWorkflow.Dispose();
                    LicensesWorkflow.Dispose();
                    RacesWorkflow.Dispose();
                    context.Dispose();
                }

                isDisposed = true;
            }
        }
        public async Task <Competition> CloneCompetitionAsync(Competition current, CompetitionCloneSettings settings)
        {
            using (var transaction = context.BeginTransaction(IsolationLevel.RepeatableRead))
                try
                {
                    var shift = settings.Starts - current.Starts;
                    var clone = new Competition
                    {
                        SerieId         = settings.CloneSerie ? current.SerieId : new Guid?(),
                        VenueCode       = settings.CloneVenue ? current.VenueCode : null,
                        Discipline      = current.Discipline,
                        Location        = current.Location,
                        LocationFlags   = current.LocationFlags,
                        Extra           = current.Extra,
                        Sponsor         = current.Sponsor,
                        Name            = settings.Name ?? current.Name,
                        Class           = current.Class,
                        LicenseIssuerId = current.LicenseIssuerId,
                        Starts          = settings.Starts,
                        Ends            = current.Ends + shift,
                        TimeZone        = current.TimeZone,
                        Culture         = current.Culture
                    };
                    await AddCompetitionAsync(clone);

                    var clonedDistances = new Dictionary <Guid, Distance>();
                    if (settings.CloneDistances)
                    {
                        foreach (var currentDistance in await DistancesWorkflow.Distances(current.Id).ToListAsync())
                        {
                            var clonedDistance = await DistancesWorkflow.CloneDistanceAsync(currentDistance, settings.DistanceCloneSettings, settings.CloneVenue, clone.Id,
                                                                                            shift);

                            clonedDistances.Add(currentDistance.Id, clonedDistance);
                        }
                    }

                    if (settings.CloneDistanceCombinations)
                    {
                        foreach (var currentDistanceCombination in await DistanceCombinationsWorkflow.Combinations(current.Id).Include(c => c.Distances).ToListAsync())
                        {
                            var clonedDistanceCombination =
                                await
                                DistanceCombinationsWorkflow.CloneDistanceCombinationAsync(currentDistanceCombination, settings.DistanceCombinationCloneSettings, clone.Id,
                                                                                           shift);

                            if (settings.CloneDistances)
                            {
                                clonedDistanceCombination.Distances = new Collection <Distance>();
                                await
                                DistanceCombinationsWorkflow.UpdateCombinationDistancesAsync(clonedDistanceCombination,
                                                                                             currentDistanceCombination.Distances.Select(d => clonedDistances[d.Id].Id).ToArray());
                            }
                        }
                    }

                    transaction.Commit();
                    return(clone);
                }
                catch
                {
                    transaction.Rollback();
                    throw;
                }
        }