| Quintiq file version 2.0 | 
| #parent: #root | 
| MethodOverride TransformDataFromSetObject ( | 
|   const LibDEF_SetObject setObject_i | 
| ) | 
| { | 
|   TextBody: | 
|   [* | 
|     /* | 
|     When receive Manufacturing demand data from DP, the following transformation is needed: | 
|     - Just create Sales Demand for within planning horizon | 
|     - Quantity wise: | 
|       1. If Q2 > Q1, take Q2 | 
|       2. if Q1 > Q2, create 2 sales demand object, where: | 
|          1. Forecast SD with value = Q1 - Q2 | 
|          2. Actual SD with value = Q2 | 
|      | 
|     *  Q1 = forecast qty | 
|        Q2 = actual sales qty | 
|      | 
|     Bear in mind that the time series is in <start>;<end|also start for next series>... format, | 
|     so, if there are 13 items in the date vector, there are actually 12 time series. | 
|     and, Dates vector has 1 element more than that in vector Quantities<1,2,3> | 
|      | 
|     1. Convert vector to DataTypes type accordingly, E.g: DateVector to DateTimes, QuantityVector to Reals | 
|     2. Find PISP | 
|     3. If PISP exists, and all vector size are same | 
|          - create SalesDemand if it doesn't exists | 
|          - update sales demand if it exists | 
|     */ | 
|      | 
|     salesDemandExternal    := setObject_i.astype( LibDEC_ManufacturingDemand ); | 
|     macroPlan              := this.GetMacroPlan(); | 
|     startOfPlanningHorizon := macroPlan.StartOfPlanningPeriod().StartDate(); | 
|     endOfPlanningHorizon   := macroPlan.End().Date();                           | 
|      | 
|     if( salesDemandExternal.Dates().Size() > 0 ) // DateTimeVector::Construct() will get error if there is nothing in the dates | 
|     { | 
|       dateTimes              := DateTimeVector::Construct( salesDemandExternal.Dates()       ).AsValues(); | 
|       forecastQuantities     := RealVector::Construct    ( salesDemandExternal.Quantities1() ).AsValues(); | 
|       actualSalesQuantities  := RealVector::Construct    ( salesDemandExternal.Quantities2() ).AsValues(); | 
|       revenues               := RealVector::Construct    ( salesDemandExternal.Quantities3() ).AsValues(); | 
|       nrOfDates              := dateTimes.Size(); | 
|       nrOfForecastQuantities := forecastQuantities.Size(); | 
|       nrOfActualQuantities   := actualSalesQuantities.Size(); | 
|       nrOfRevenues           := revenues.Size(); | 
|      | 
|       // Find create pisp if it doesn't already exist | 
|       pisp := ProductInStockingPoint_MP::Create( salesDemandExternal.ProductID(), salesDemandExternal.LocationID() ); | 
|      | 
|       if( not isnull( pisp ) | 
|           and nrOfDates = nrOfForecastQuantities + 1 | 
|           and nrOfForecastQuantities = nrOfActualQuantities | 
|           and nrOfActualQuantities   = nrOfRevenues ) | 
|       { | 
|         for( i := 0; i < dateTimes.Size() - 1 ; i++ ) | 
|         { | 
|           startDate := dateTimes.Element( i ).Date(); | 
|           endDate   := dateTimes.Element( i + 1 ).Date(); | 
|           revenue   := ifexpr( revenues.Element( i ).IsNaN(), 0.0, revenues.Element( i ) ); //Translate NANs to zero-s                         | 
|           forecastQuantity := ifexpr( forecastQuantities.Element( i ).IsNaN(), 0.0, forecastQuantities.Element( i ) );    | 
|           actualQuantity   := ifexpr( actualSalesQuantities.Element( i ).IsNaN(), 0.0, actualSalesQuantities.Element( i ) ); | 
|           demanduncertaintypercentage := [Real] salesDemandExternal.DemandUncertaintyPercentage(); | 
|      | 
|      | 
|           if( endDate > startOfPlanningHorizon | 
|               and startDate < endOfPlanningHorizon )  // ONLY create sales demand within planning horizon | 
|           { | 
|             if( actualQuantity > 0.0 ) | 
|             { | 
|               // create HIGH priority sales demand with quantity = actual quantity | 
|               quantity               := actualQuantity; | 
|               priorityName           := DataTransformationManufacturingDemand::FormatPriorityName( salesDemandExternal.PriorityID(), DataTransformationManufacturingDemand::SalesDemandPriorityName_High() ); | 
|               formattedSalesDemandID := DataTransformationManufacturingDemand::FormatSalesDemandID( salesDemandExternal.ID(), startDate, priorityName ); | 
|               this.CreateUpdateSalesDemand( pisp.Product_MP(), pisp.StockingPoint_MP(), salesDemandExternal, | 
|                                             formattedSalesDemandID, startDate, endDate, quantity, revenue, priorityName, demanduncertaintypercentage, | 
|                                             false ); | 
|             } | 
|      | 
|             if( forecastQuantity > actualQuantity | 
|                 and forecastQuantity > 0.0 ) // make sure forecast quantity > 0.0 | 
|             { | 
|               // create NORMAL priority sales demand with quantity = forecast - actual quantity | 
|               quantity               := forecastQuantity - actualQuantity; | 
|               priorityName           := DataTransformationManufacturingDemand::FormatPriorityName( salesDemandExternal.PriorityID(), DataTransformationManufacturingDemand::SalesDemandPriorityName_Normal() ); | 
|               formattedSalesDemandID := DataTransformationManufacturingDemand::FormatSalesDemandID( salesDemandExternal.ID(), startDate, priorityName ); | 
|               this.CreateUpdateSalesDemand( pisp.Product_MP(), pisp.StockingPoint_MP(), salesDemandExternal, | 
|                                             formattedSalesDemandID, startDate, endDate, quantity, revenue, priorityName, demanduncertaintypercentage, | 
|                                             false ); | 
|             } | 
|           } | 
|         } | 
|       } | 
|     } | 
|   *] | 
| } |