| Quintiq file version 2.0 | 
| #parent: #root | 
| Method GenerateCombis | 
| { | 
|   TextBody: | 
|   [* | 
|     /////////////////////////////////////////////////////////////////////////////////////////////// | 
|     //Collect the combis and transitions that can be used to start campaigns in this period | 
|     /////////////////////////////////////////////////////////////////////////////////////////////// | 
|     if( this.IsFixed() ) | 
|     { | 
|       //Create a combi for the fixed campaign or transition | 
|       if( not isnull( this.Campaign_MP() ) ) | 
|       { | 
|         OptCampaignCombi::Create( this, this.Campaign_MP() );   | 
|          | 
|       } | 
|       if( not isnull( this.Transition_MP() ) ) | 
|       { | 
|         OptCampaignCombi::Create( this, this.Transition_MP() );  | 
|       }    | 
|     } | 
|     else  | 
|     { | 
|       campaigntypes := construct( CampaignType_MPs ); | 
|       transitiontypes := construct( TransitionType_MPs ); | 
|       previousocusp := this.PreviousSubPeriod() | 
|       lastcampaign := this.OptCampaignUnit().LastCampaignBeforeOptHorizon() | 
|       lasttransition := this.OptCampaignUnit().LastTransitionBeforeOptHorizon(); | 
|       if( not isnull( previousocusp ) and not previousocusp.IsFixed() ) | 
|       { | 
|         //Combis in this period can start with a campaign/transitin that can follow the last type in a combi of the previous period  | 
|         //but they can also extend the last state of the combi so we need to capture both possibilities | 
|         lastelementsinprevocusp := selectset( this,  | 
|                                               OptCampaignUnit.OptCampaignUnitSubPeriod.OptCampaignCombi.LastCombiElement, | 
|                                               ele, | 
|                                               ele.OptCampaignUnitSubPeriod() = previousocusp ) | 
|          | 
|         campaigntypesthatfollow := selectset( lastelementsinprevocusp,  | 
|                                               Elements.astype( OptCampaignCombiElementTransition ).TransitionType_MP.ToCampaignType,  | 
|                                               ct,  | 
|                                               true );  | 
|                                                | 
|         campaigntypesthatextend := selectset( lastelementsinprevocusp,  | 
|                                               Elements.astype( OptCampaignCombiElementCampaign ).CampaignType_MP,  | 
|                                               ct,  | 
|                                               true ) | 
|                                                | 
|         campaigntypes := ifexpr( previousocusp.IsFixed(), &campaigntypesthatfollow, &campaigntypesthatextend ); | 
|         campaigntypes.Sort( "Name", true ); | 
|                                                  | 
|         transitiontypes := selectset( lastelementsinprevocusp,  | 
|                                       Elements.astype( OptCampaignCombiElementTransition ).TransitionType_MP,  | 
|                                       t, true ); | 
|          | 
|         transitiontypes.Sort( "Name", true ); | 
|          | 
|       } | 
|       else if( not isnull( lastcampaign ) ) | 
|       { | 
|         //if there is a campaign set as the last one before campaign horizon, we need to continue this campaign | 
|         campaigntypes.Add( lastcampaign.CampaignType_MP() );  | 
|         transitiontypes := null( TransitionType_MPs ) | 
|       } | 
|       else if ( not isnull( lasttransition ) ) | 
|       { | 
|         //If there is a transition set as the last one before campaign horizon, we need to continue this transition | 
|         campaigntypes := null( CampaignType_MPs );  | 
|         transitiontypes.Add( lasttransition.TransitionType_MP() ) | 
|       } | 
|       else | 
|       { | 
|         //If there are not restrictions just create combis for every possible combination of campaigns | 
|         //but we don't want to start the plan with a transition | 
|         campaigntypes := selectsortedset( this, OptCampaignUnit.Unit.CampaignType_MP, ct, true, ct.Name() );  | 
|         transitiontypes := null( TransitionType_MPs ) | 
|       } | 
|       /////////////////////////////////////////////////////////////////////////////////////////////// | 
|       //Generate the start combis based on the possible campaign and transition types  | 
|       /////////////////////////////////////////////////////////////////////////////////////////////// | 
|       //Add combis that start with a campaign | 
|       traverse( campaigntypes, Elements, ct ) | 
|       { | 
|         OptCampaignCombi::Create( this, ct );  | 
|       } | 
|        | 
|       //Add combis that start with a transistion | 
|       traverse( transitiontypes, Elements, tt ) | 
|       { | 
|         OptCampaignCombi::Create( this, tt ); | 
|       } | 
|     } | 
|      | 
|     /////////////////////////////////////////////////////////////////////////////////////////////// | 
|     //Extend/expand the start combis until all combinations are found | 
|     /////////////////////////////////////////////////////////////////////////////////////////////// | 
|     this.ExtendCombis(); | 
|   *] | 
| } |