Exemple #1
0
        /// <summary>
        ///
        ///     Intents:
        ///
        ///     E = Editable , !E = NotEditable
        ///     R = Removable, !R = NotRemovable
        ///
        ///     This table shows how conflicts are solved
        ///     on a specific market
        ///
        ///     (Rule 1, Rule 2) => Result
        ///     (E, R)  => E
        ///     (E, !R) => E
        ///     (E, E1) => See below
        ///     (E, !E) => !E
        ///
        ///     (R, !R) => !R
        ///     (R, R)  => R
        ///     (R, !E) => R
        ///
        ///     (!R, !R) => !R
        ///     (!R, !E) => !E + !R
        ///
        ///     (!E, !E) => !E
        ///
        ///     When there are more than one rule that want to edit a specific market, the
        ///     MarketRuleEditIntent.OperationType is considered.
        ///
        ///     OperationType can be: CHANGE_SELECTIONS (CS), ADD_SELECTIONS (AS), REMOVE_SELECTIONS (RS), CHANGE_DATA (CD)
        ///
        ///     (CS, AS) => CS + AS (changing operation will be perfomed on the existing selections. Newly added selections will not be edited)
        ///     (CS, RS) => CS
        ///     (CS, CS) => CS + CS (this might cause unexpected results)
        ///     (CS, CD) => CS + CD
        ///
        ///     (AS, RS) => RS + AS (existing selection will be removed and only after that the new one are added)
        ///     (AS, CD) => AS + CD
        ///     (AS, AS) => AS + AS
        ///
        ///     (CD, CD) => CD + CD (this might cause unexpected results)
        ///     (CD, RS) => CD + RS
        ///
        ///     (RS, RS) => RS + RS
        ///
        /// </summary>
        /// <param name="fixture"></param>
        /// <param name="intents"></param>
        private void MergeIntents(Fixture fixture, Dictionary <IMarketRule, IMarketRuleResultIntent> intents, bool isRemovalDisabled = false)
        {
            Dictionary <Market, bool>   toRemove = new Dictionary <Market, bool>();
            Dictionary <Market, string> dueRule  = new Dictionary <Market, string>();

            //this creates empty dictionary the object there is only to generate the type
            var toAdd = Anonymous.CreateDictionaryWithAnonymousObject(String.Empty,
                                                                      new
            {
                Market = new Market(),
                Intent = new MarketRuleAddIntent(MarketRuleAddIntent.OperationType.ADD_SELECTIONS)
            });


            Dictionary <Market, Dictionary <MarketRuleEditIntent, string> > toedit = new Dictionary <Market, Dictionary <MarketRuleEditIntent, string> >();

            foreach (var rule in intents.Keys)
            {
                var intent = intents[rule];

                /* "toremove" lists all the markets that a rule wants to remove.
                 * Those that will be removed are only those
                 * whose flag is set to true. Those that have the flag
                 * set to false are markets that some rule wanted to
                 * remove but some other rule marked them as not
                 * removable. As we follow a conservative approch
                 * we only remove a market if no other rule specified
                 * otherwise.
                 */

                if (!isRemovalDisabled)
                {
                    foreach (var mkt in intent.RemovableMarkets)
                    {
                        // if it already contains the market, don't do
                        // anything as the flag could be "false"
                        if (!toRemove.ContainsKey(mkt))
                        {
                            toRemove.Add(mkt, true);
                            dueRule[mkt] = rule.Name;
                        }
                    }
                }

                foreach (var mkt in intent.UnRemovableMarkets)
                {
                    // if it is already present, then
                    // set its flag to false
                    if (toRemove.ContainsKey(mkt))
                    {
                        toRemove[mkt] = false;
                    }
                    else
                    {
                        toRemove.Add(mkt, false);
                    }
                }

                /* For "editable" markets we follow the same
                 * reasoning we do for removing the markets,
                 * except here the flag is the action to perform
                 * or null if a rule marked the market to be
                 * not-editable
                 */
                foreach (var mkt in intent.EditedMarkets)
                {
                    if (!toedit.ContainsKey(mkt))
                    {
                        toedit.Add(mkt, new Dictionary <MarketRuleEditIntent, string> {
                            { intent.GetEditingAction(mkt), rule.Name }
                        });
                    }
                    else if (toedit[mkt] != null)
                    {
                        toedit[mkt].Add(intent.GetEditingAction(mkt), rule.Name);
                    }
                }

                foreach (var mkt in intent.UnEditableMarkets)
                {
                    if (toedit.ContainsKey(mkt))
                    {
                        toedit[mkt] = null;
                    }
                    else
                    {
                        toedit.Add(mkt, null);
                    }
                }

                foreach (var mkt in intent.NewMarkets)
                {
                    if (toAdd.ContainsKey(mkt.Id))
                    {
                        var firstAddition = toAdd[mkt.Id];
                        if (ShouldKeepFirstMarket(firstAddition.Intent, intent.GetAddAction(mkt)))
                        {
                            continue;
                        }
                    }

                    toAdd[mkt.Id] = new { Market = mkt, Intent = intent.GetAddAction(mkt) };
                    dueRule[mkt]  = rule.Name;
                }
            }

            // ADD
            foreach (var addItem in toAdd)
            {
                var market = addItem.Value.Market;

                _logger.DebugFormat("Adding {0} to fixtureId={1} due rule={2}", market, fixture.Id, dueRule[market]);

                // as we might have changed import details of the market, we need to update the market state
                var marketState = _currentTransaction[market.Id];
                if (marketState != null)
                {
                    ((IUpdatableMarketState)marketState).Update(market, false);
                }

                fixture.Markets.Add(market);
            }

            // EDIT
            MergeEditIntents(fixture, toedit);

            if (isRemovalDisabled)
            {
                return;
            }

            // REMOVE
            foreach (var mkt in toRemove.Keys)
            {
                // we need to check that a removable market
                // wasn't marked as editable or not editable
                if (toRemove[mkt] && !toedit.ContainsKey(mkt))
                {
                    _logger.DebugFormat("Removing {0} of fixtureId={1} due rule={2}", mkt, fixture.Id, dueRule[mkt]);
                    fixture.Markets.Remove(mkt);
                }
            }
        }