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(); 
 | 
  *] 
 | 
} 
 |