Quintiq file version 2.0 
 | 
#parent: #root 
 | 
Method GetNonFinancialKPI ( 
 | 
  Number level, 
 | 
  Boolean includeintbased, 
 | 
  Boolean intbasedonly, 
 | 
  output String msg_o, 
 | 
  const WeightLevelNonFinancial weightlevels, 
 | 
  output Real minweightused, 
 | 
  output Real maxweightused 
 | 
) as Real 
 | 
{ 
 | 
  TextBody: 
 | 
  [* 
 | 
    // Storing of goal value to instances 
 | 
     
 | 
    msg := '';  
 | 
    dummy1 := 0.0;  
 | 
    dummy2 := 0.0;  
 | 
    dummy3 := 0.0;  
 | 
    value := 0.0;  
 | 
    subopt := this.Suboptimizer().astype( CapacityPlanningSuboptimizer );  
 | 
    mp := subopt.Run().Optimization().astype( Optimization ).MacroPlan();  
 | 
    if ( not isnull( weightlevels ) )  
 | 
    { 
 | 
      eis := mp.OptimizerMetaEIS();  
 | 
      if ( not eis.IsNeedEstimatedImprovementScores()  ) // used so we can also write scores to snapshot in smartplan , full optimizer 
 | 
      { 
 | 
        eis.TemporaryForScoreWriting( true );  
 | 
        Transaction::Transaction().Propagate( attribute( OptimizerMetaEIS, KPIBalanceViolation ) );  
 | 
        Transaction::Transaction().Propagate( attribute( OptimizerMetaEIS, KPILotSizeTotal ) );  
 | 
        Transaction::Transaction().Propagate( attribute( OptimizerMetaEIS, KPIMaximumInventory ) );  
 | 
        Transaction::Transaction().Propagate( attribute( OptimizerMetaEIS, KPIMinimumInventory ) );  
 | 
        Transaction::Transaction().Propagate( attribute( OptimizerMetaEIS, KPITargetInventory ) );  
 | 
        Transaction::Transaction().Propagate( attribute( OptimizerMetaEIS, KPISalesDemandPriority ) );                                                                                                                       
 | 
        eis.TemporaryForScoreWriting( false );  
 | 
      } 
 | 
       
 | 
      if ( intbasedonly )  
 | 
      { 
 | 
        valuelotsize :=  ifexpr( level = weightlevels.LotSizeLevel(), -eis.KPILotSizeTotal() * this.AdjustMinMax( minweightused, maxweightused, weightlevels.LotSizeWeight() ), 0.0  ) 
 | 
        msg := msg + 'KPILotSize=' + [String]valuelotsize + String::NewLine(); 
 | 
        valueprocessminqty :=  ifexpr( level = weightlevels.SlackLevel(), // note process min qty is implemented with BIGM. It should be score on the hidden slack level  
 | 
                                       -mp.GetKPIProcessMinimumQuantity(this.CutOffProcessMinQtyKPI() ) * this.AdjustMinMax( minweightused, maxweightused, weightlevels.ProcessMinimumQuantityWeight() ),  0.0 )  
 | 
        msg := msg + 'KPIProcessMinQty=' + [String] valueprocessminqty + String::NewLine(); 
 | 
        value := valuelotsize + valueprocessminqty;  
 | 
      } 
 | 
      else 
 | 
      {  
 | 
        valuelotsize :=  ifexpr( includeintbased and level = weightlevels.LotSizeLevel(), -eis.KPILotSizeTotal() * this.AdjustMinMax( minweightused, maxweightused, weightlevels.LotSizeWeight() ), 0.0  ) 
 | 
        msg := msg + 'KPILotSize=' + [String]valuelotsize + String::NewLine(); 
 | 
        valueprocessminqty :=  ifexpr( includeintbased and level =weightlevels.SlackLevel(), // note process min qty is implemented with BIGM. It should be score on the hidden slack level  
 | 
                                       -mp.GetKPIProcessMinimumQuantity( this.CutOffProcessMinQtyKPI()) * this.AdjustMinMax( minweightused, maxweightused, weightlevels.ProcessMinimumQuantityWeight() ),  0.0 )  
 | 
        msg := msg + 'KPIProcessMinQty=' + [String] valueprocessminqty + String::NewLine(); 
 | 
         
 | 
        valuecampaign := ifexpr( level = weightlevels.CampaignLevel(),  
 | 
                                 -RollbackKPIMeta::GetCampaignScore( weightlevels.RunContextForCapacityPlanning(), mp, dummy1, dummy2, dummy3 ) * this.AdjustMinMax( minweightused, maxweightused, weightlevels.CampaignWeight() ),  0.0 );  
 | 
        msg := msg + 'KPICampagin=' + [String]valuecampaign + String::NewLine();  
 | 
        valuefulfillment :=  ifexpr( level = weightlevels.FulfillmentLevel(), mp.GetKPIFulfillment() * this.AdjustMinMax( minweightused, maxweightused, weightlevels.FulfillmentWeight() ), 0.0 );  
 | 
        msg := msg + 'KPIfulfillment=' + [String]valuefulfillment + String::NewLine(); 
 | 
        valueinventorymix :=  ifexpr( level = weightlevels.InventoryMixBalancingLevel(), -mp.GetKPIInventoryMixBalancing() * this.AdjustMinMax( minweightused, maxweightused, weightlevels.InventoryMixBalancingWeight() ), 0.0  )   
 | 
        msg := msg + 'KPIInventoryMixBalancing=' + [String]valueinventorymix + String::NewLine(); 
 | 
        valuemaxinventory :=  ifexpr( level = weightlevels.MaximumInventoryLevel(),  -eis.KPIMaximumInventory() * this.AdjustMinMax( minweightused, maxweightused, weightlevels.MaximumInventoryLevelWeight() ), 0.0  )  
 | 
        msg := msg + 'KPIMaxInventoryLevel=' + [String] valuemaxinventory + String::NewLine(); 
 | 
        valuemininventory := ifexpr( level = weightlevels.MinimumInventoryLevel(), -eis.KPIMinimumInventory() * this.AdjustMinMax( minweightused, maxweightused, weightlevels.MinimumInventoryLevelWeight() ), 0.0  ) 
 | 
        msg := msg + 'KPIMinInventoryLevel=' + [String] valuemininventory + String::NewLine(); 
 | 
        valuesupplytarget :=  ifexpr( level = weightlevels.SupplyTargetLevel(), -mp.GetKPISupplyTarget() * this.AdjustMinMax( minweightused, maxweightused, weightlevels.SupplyTargetWeight() ),  0.0 ) 
 | 
        msg := msg + 'KPISupplyTarget=' + [String]valuesupplytarget + String::NewLine(); 
 | 
        valueminsupply :=  ifexpr( level = weightlevels.MinimumSupplyLevel(),  -mp.GetKPIMinimumSupply() * this.AdjustMinMax( minweightused, maxweightused, weightlevels.MinimumSupplyWeight() ), 0.0  )  
 | 
        msg := msg + 'KPIMinSupply=' + [String] valueminsupply + String::NewLine(); 
 | 
        valuemaxsupply :=  ifexpr( level = weightlevels.MaximumSupplyLevel(),  -mp.GetKPIMaximumSupply() * this.AdjustMinMax( minweightused, maxweightused, weightlevels.MaximumSupplyWeight() ), 0.0  )  
 | 
        msg := msg + 'KPIMaxSupply=' + [String] valuemaxsupply + String::NewLine(); 
 | 
        valueminunitcap :=  ifexpr( level = weightlevels.MinimumUnitCapacityLevel(), -mp.GetKPIUnitCapacityNotMet() * this.AdjustMinMax( minweightused, maxweightused, weightlevels.MinimumUnitCapacityWeight() ), 0.0 )  
 | 
        msg := msg + 'KPIMinUnitCapacity=' + [String] valueminunitcap + String::NewLine(); 
 | 
        valuepostpone :=  ifexpr( level = weightlevels.PostponementPenaltyLevel(),  -mp.GetKPIPostponementPenalty() * this.AdjustMinMax( minweightused, maxweightused, weightlevels.PostponementPenaltyWeight() ), 0.0  )  
 | 
        msg := msg + 'KPIPostponementPenalty=' + [String] valuepostpone + String::NewLine(); 
 | 
        valueprocessmaxqty :=  ifexpr( level = weightlevels.ProcessMaximumQuantityLevel(),  -mp.GetKPIProcessMaximumQuantity() * this.AdjustMinMax( minweightused, maxweightused, weightlevels.ProcessMaximumQuantityWeight() ), 0.0  )  
 | 
        msg := msg + 'KPIProcessMaxQty=' + [String] valueprocessmaxqty + String::NewLine(); 
 | 
       
 | 
        valuesalesdemandprio :=  ifexpr( level = weightlevels.SalesDemandPriorityLevel(), eis.KPISalesDemandPriority() * this.AdjustMinMax( minweightused, maxweightused, weightlevels.SalesDemandPriorityWeight() ), 0.0   ) // use attribute to avoid expensive kpi method 
 | 
        msg := msg + 'KPISalesDemandPrio=' + [String] valuesalesdemandprio + String::NewLine(); 
 | 
        valuefftarget :=  ifexpr( level = weightlevels.FulfillmentTargetLevel(), mp.GetKPIFulfillmentTargetOpt() * this.AdjustMinMax( minweightused, maxweightused, weightlevels.FulfillmentTargetWeight() ),   0.0  )  
 | 
        msg := msg + 'KPIFulfillmentTarget=' + [String] valuefftarget + String::NewLine(); // note KPIFulfillmentTarget is a poor KPI to gauge convergence for  
 | 
        valueservice :=  ifexpr( level = weightlevels.ServiceLevelLevel(), mp.GetKPIServiceLevel() * this.AdjustMinMax( minweightused, maxweightused, weightlevels.ServiceLevelWeight() ), 0.0  ) 
 | 
        msg := msg + 'KPIServiceLevel' + [String] valueservice + String::NewLine(); 
 | 
        valuespcap :=  ifexpr( level = weightlevels.StockingPointCapacityLevel(), -mp.GetKPIStockingPointCapacity() * this.AdjustMinMax( minweightused, maxweightused, weightlevels.StockingPointCapacityWeight() ), 0.0 )  
 | 
        msg := msg + 'KPISPCapacity=' + [String] valuespcap + String::NewLine(); 
 | 
        valuetinvlevel :=  ifexpr( level = weightlevels.TargetInventoryLevel(), -eis.KPITargetInventory() * this.AdjustMinMax( minweightused, maxweightused, weightlevels.TargetInventoryLevelWeight() ), 0.0 )  
 | 
        msg := msg + 'KPITargetInvLevel=' + [String] valuetinvlevel + String::NewLine(); 
 | 
        valueunitcap :=  ifexpr( level = weightlevels.UnitCapacityLevel(), -mp.GetKPIUnitCapacity() * this.AdjustMinMax( minweightused, maxweightused, weightlevels.UnitCapacityWeight() ), 0.0 ) 
 | 
        msg := msg + 'KPIUnitCap=' + [String] valueunitcap + String::NewLine(); 
 | 
        valuebalance := ifexpr ( level = weightlevels.SlackLevel(), -eis.KPIBalanceViolation() * this.AdjustMinMax( minweightused, maxweightused, weightlevels.SlackWeight() ), 0.0 ); // hidden balance KPI in level 1 
 | 
        msg := msg + 'KPIBalanceViolation=' + [String] valuebalance + String::NewLine();  
 | 
        valuecampaigncombislack := ifexpr( level = weightlevels.SlackLevel(), -RollbackKPIMeta::GetCampaignCombiSlackScore( mp, dummy1, dummy2, weightlevels.RunContextForCapacityPlanning().UseCampaignSequenceOptimizer() ), 0.0 );  
 | 
        msg := msg + 'CampaignCombiSlack=' + [String] valuecampaigncombislack + String::NewLine();  
 | 
        valueshiftmindurqationslack := ifexpr( level = weightlevels.SlackLevel(), -RollbackKPIMeta::GetShiftOptimizerMinDurationSlackScore( mp, subopt ), 0.0 );  
 | 
        msg := msg + 'ShiftOptimizerMinDurationSlack=' + [String] valueshiftmindurqationslack + String::NewLine();  
 | 
        valueblending := ifexpr(  level = weightlevels.BlendingLevel(), -mp.GetKPIBlending( this.AccuracyBlendingKPI() ) * this.AdjustMinMax( minweightused, maxweightused, weightlevels.BlendingWeight() ), 0.0 );  
 | 
        msg := msg + 'KPIblending=' + [String] valueblending + String::NewLine();  
 | 
        valuetotalexpired := ifexpr(  level = weightlevels.ExpiredQtyLevel(), -mp.GetKPITotalExpiredQuantity() * this.AdjustMinMax( minweightused, maxweightused, weightlevels.ExpiredQtyWeight() ), 0.0 );  
 | 
        msg := msg + 'KPITotalExpiredQuantity=' + [String] valuetotalexpired + String::NewLine();  
 | 
        valueco2emission := ifexpr( level = weightlevels.CO2EmissionLevel(), -mp.GetKPICO2Emission() * this.AdjustMinMax( minweightused, maxweightused, weightlevels.CO2EmissionWeight() ), 0.0 ); 
 | 
        msg := msg + 'KPICO2Emission=' + [String] valueco2emission + String::NewLine(); 
 | 
         
 | 
        value := valuecampaign  
 | 
                 + valuefulfillment  
 | 
                 + valueinventorymix  
 | 
                 + valuelotsize  
 | 
                 + valuemaxinventory  
 | 
                 + valuemininventory  
 | 
                 + valuesupplytarget  
 | 
                 + valueminsupply  
 | 
                 + valuemaxsupply  
 | 
                 + valueminunitcap  
 | 
                 + valuepostpone  
 | 
                 + valueprocessmaxqty  
 | 
                 + valueprocessminqty  
 | 
                 + valuesalesdemandprio  
 | 
                 + valuefftarget  
 | 
                 + valueservice  
 | 
                 + valuespcap  
 | 
                 + valuetinvlevel  
 | 
                 + valueunitcap  
 | 
                 + valuebalance  
 | 
                 + valuecampaigncombislack 
 | 
                 + valueshiftmindurqationslack 
 | 
                 + valueblending  
 | 
                 + valuetotalexpired 
 | 
                 + valueco2emission;  
 | 
         
 | 
        msg_o := msg;           
 | 
      } 
 | 
    } 
 | 
    value := ifexpr( this.RoundPuzzleScoreDecimal() >= 0, value.Round( this.RoundPuzzleScoreDecimal() ), value ); // negative means no round 
 | 
     
 | 
    return value; 
 | 
  *] 
 | 
  InterfaceProperties { Accessibility: 'Module' } 
 | 
} 
 |