Quintiq file version 2.0
|
#parent: #root
|
Method ChangeDatasetAndExportData (
|
LibSCIIntegrationInterface libsci,
|
LibSCIScenario libsciscenario
|
) #extension
|
{
|
TextBody:
|
[*
|
// LibSCIScenario
|
libsci.AddScenarioForExport( libsciscenario.Uri(), libsciscenario.Name(), libsciscenario.Assumptions() ,libsciscenario.IsCurrent(), libsciscenario.IsBase() );
|
m := stream[Void]::Success();
|
|
options := DatasetFindOptions::Construct( libsciscenario.Uri() );
|
key := DatasetController::FindUnique( options );
|
// Prevent Empty Key and error in UTF
|
if( key <> Key::ZeroKey() )
|
{
|
MDSMacroPlan::Root( key )
|
->( macroplan )
|
{
|
startofplanning := macroplan.StartOfPlanning();
|
firstplanningstart := macroplan.FirstPlanningPeriod().Start();
|
endofplanning:= macroplan.LastPlanningPeriod().End();
|
bottleneckthreshold := macroplan.GlobalParameters_MP().UnitLowerBottleneckThreshold();
|
resources:= selectset( macroplan, Unit, resource, resource.HasCapacityTypeTime() and resource.Child( relsize ) = 0 );
|
safetystocks := selectsortedset( macroplan, Product_MP.SafetyStock, ss, ss.Start(), ss.ProductID(), ss.StockingPointID() );
|
pisphasiventorylevelend := selectset( macroplan, Product_MP.ProductInStockingPoint_MP, pisp, pisp.HasInventoryLevelEndInPlanningPeriod() );
|
|
// Product_MP -> Item
|
traverse( macroplan, Product_MP, p, not p.IsSystem() )
|
{
|
libsci.AddItemForExport( p.ID(), p.Name(), p.ParentID() )
|
}
|
|
// Resource
|
traverse( macroplan, Unit, u )
|
{
|
libsci.AddResourceForExport( u.ID(), u.Name(), u.ParentUnitID() )
|
libsci.AddMaximumProjectedResourceUtilizationExport( u.Name(), libsciscenario.Name(), startofplanning, endofplanning, bottleneckthreshold );
|
|
if ( libsciscenario.IsCurrent() and firstplanningstart < startofplanning )
|
{
|
libsci.AddMaximumResourceUtilizationExport( u.Name(), firstplanningstart, startofplanning, bottleneckthreshold );
|
}
|
}
|
|
// Period_MP -> PeriodOfTime
|
periods := selectset( macroplan, PeriodSpecification_MP, ps, not ps.IsDummyPlanningPeriod() );
|
traverse( periods, Elements.Period_MP, p )
|
{
|
libsci.AddPeriodOfTimeForExport( p.StartDate(), p.EndDate(), p.PeriodSpecificationID(), p.TimeUnit() )
|
}
|
|
// PeriodSpecifications_MP -> PeriodOfTimeDefinition
|
traverse( macroplan, PeriodSpecification_MP, ps, not ps.IsDummyPlanningPeriod() )
|
{
|
libsci.AddPeriodOfTimeDefinitionForExport( ps.ID(), ps.TimeUnit() )
|
}
|
|
// SalesSegments_MP -> SalesSegment
|
traverse( macroplan, SalesSegment_MP, ss )
|
{
|
libsci.AddSaleSegmentForExport( ss.Name(), ss.ParentName() )
|
}
|
|
// StockingPoint_MP -> StockLocation
|
traverse( macroplan, StockingPoint_MP, sp, not sp.IsSystem() )
|
{
|
libsci.AddStockLocationForExport( sp.ID(), sp.Name() )
|
}
|
|
traverse( resources, Elements.PlanningUnitPeriod.astype( UnitPeriodTime ), unitperiodtime , not unitperiodtime.Period_MP().IsHistorical() )
|
{
|
libsci.AddPlannedResourceUtilizationForExport( libsciscenario.Uri(), unitperiodtime.Unit().ID(), unitperiodtime.StartDate(),
|
unitperiodtime.End().Date(), unitperiodtime.TotalAvailableCapacity().HoursAsReal(),
|
unitperiodtime.GetDisplayUsedCapacity().HoursAsReal() );
|
}
|
|
// Only export TargetFillRate / Actuals for IsCurrent LibScenario
|
if( libsciscenario.IsCurrent() )
|
{
|
libsci.AddCompanyForExport( startofplanning, macroplan.BaseCurrency().Symbol() );
|
|
traverse( macroplan, FulfillmentTarget,ft )
|
{
|
// FulfillmentTarget -> TargetFillRateQuantity
|
libsci.AddTargetFillRateQuantityForExport( ft.ProductID(), ft.StockingPointID(), ft.SalesSegmentName(), ft.Start(), ft.End(), ft.TargetPercentage(), ft.TargetPercentage() );
|
// FulfillmentTarget -> TargetFillRateRevenue
|
libsci.AddTargetFillRateRevenueForExport( ft.ProductID(), ft.StockingPointID(), ft.SalesSegmentName(), ft.Start(), ft.End(), ft.TargetPercentage(), ft.TargetPercentage() );
|
}
|
|
traverse( macroplan, Period_MP, p, p.IsHistorical() )
|
{
|
sdips := selectset( p, ProductInStockingPointInPeriod.SalesDemandInPeriodBase, sdip, not sdip.istype( DisaggregatedSalesDemandInPeriod ) );
|
salessegments := selectset( sdips, Elements.AsPlanningSalesDemandInPeriod.SalesSegment_MP, ss, true );
|
|
traverse( sdips, Elements.AsSalesDemandInPeriodBase, pispip )
|
{
|
traverse( salessegments, Elements, ss )
|
{
|
quantity := 0.0;
|
fulfilledQuantity := 0.0;
|
revenueQuantity := 0.0;
|
revenueFulfilled := 0.0;
|
hasdata := false;
|
|
traverse( pispip, SalesDemandInPeriodBase, sdipb, sdipb.SalesSegmentName() = ss.Name() and not sdipb.istype( DisaggregatedSalesDemandInPeriod ) )
|
{
|
quantity := quantity + sdipb.Quantity();
|
fulfilledQuantity := fulfilledQuantity + sdipb.FulfilledQuantity();
|
revenueQuantity := revenueQuantity + sdipb.Quantity() * sdipb.BasePricePerQuantity();
|
revenueFulfilled := revenueFulfilled + sdipb.FulfilledQuantity() * sdipb.BasePricePerQuantity();
|
hasdata := true;
|
}
|
|
if( hasdata )
|
{
|
// SalesDemandInPeriod -> ActualSales
|
libsci.AddActualSalesForExport( pispip.ProductInStockingPoint_MP().ProductID(), pispip.ProductInStockingPoint_MP().StockingPointID(), ss.Name(), p.StartDate(), p.EndDate(), fulfilledQuantity, revenueFulfilled );
|
// SalesDemandInPeriod -> TotalOrders
|
libsci.AddTotalOrdersForExport( pispip.ProductInStockingPoint_MP().ProductID(), pispip.ProductInStockingPoint_MP().StockingPointID(), ss.Name(), p.StartDate(), p.EndDate(), quantity, revenueQuantity );
|
}
|
}
|
}
|
|
// Export inventory level from historical period
|
traverse( p, ProductInStockingPointInPeriod.astype( ProductInStockingPointInPeriodPlanningLeaf ), pispip, pispip.ProductInStockingPoint_MP().HasInventoryLevelEndInHistoricalPeriod() )
|
{
|
pisp := pispip.ProductInStockingPoint_MP();
|
item := pisp.Product_MP().Name();
|
stocklocation := pisp.StockingPoint_MP().Name();
|
libsci.AddActualInventoryLevelForExport( item, stocklocation, p.Start(), p.End(), pispip.InventoryLevelEnd() );
|
}
|
|
}//IsHistorical Period
|
|
traverse( resources, Elements.PlanningUnitPeriod.astype( UnitPeriodTime ), unitperiodtime, unitperiodtime.Period_MP().IsHistorical() )
|
{
|
actual := ifexpr( unitperiodtime.HasActual(), unitperiodtime.ActualTotalAvailableCapacity(), unitperiodtime.TotalAvailableCapacity().HoursAsReal() );
|
used := ifexpr( unitperiodtime.HasActual(), unitperiodtime.ActualUtilizationPercentage()/100.0 * unitperiodtime.ActualTotalAvailableCapacity(), unitperiodtime.GetDisplayUsedCapacity().HoursAsReal() );
|
libsci.AddActualResourceUtilizationForExport( unitperiodtime.Unit().ID(), unitperiodtime.StartDate(),
|
unitperiodtime.End().Date(), actual,
|
used );
|
}
|
// MinimumResourceUtilization
|
traverse( resources, Elements, resource )
|
{
|
unitavailabilities := selectsortedset( resource, UnitAvailability, ua, ua.Start() < startofplanning, ua.Start() );
|
for( i:=0; i<unitavailabilities.Size(); i++ )
|
{
|
endtime := minvalue( guard( unitavailabilities.Element( i + 1 ).Start(), startofplanning ), startofplanning );
|
this.AddMinimumResourceUtilizationExport( resource.Name(), unitavailabilities.Element( i ).Start(), endtime, unitavailabilities.Element( i ).MinimumLoadThreshold() );
|
|
}
|
|
}
|
// Export of Historical InventoryValue
|
inventoryvalues := selectsortedset( macroplan, Product_MP.InventoryValueAndCost, inv,
|
inv.Start().DateTime() < macroplan.StartOfPlanning(),
|
inv.ProductID(), inv.StockingPointID(), inv.Start() )
|
|
this.AddInventoryValue( libsciscenario.Name(), macroplan, inventoryvalues, true );
|
|
inventorytargets := selectsortedset( macroplan, Product_MP.InventorySpecification, it,
|
it.HasMaxLevel() and not it.HasMaxLevelInDays() and it.Start().DateTime() < startofplanning ,
|
it.Start(), it.ProductID(), it.StockingPointID() );
|
this.AddMaximumInventoryValue( libsciscenario, macroplan, inventorytargets, true );
|
|
}// End of only for IsCurrent scenario
|
// MinimumProjectedResourceUtilization
|
traverse( resources, Elements, resource )
|
{
|
unitavailabilities := selectsortedset( resource, UnitAvailability, ua, ua.Start() );
|
|
start := startofplanning;
|
end := endofplanning;
|
i := 0;
|
skip := false;
|
while ( i < unitavailabilities.Size() )
|
{
|
current := unitavailabilities.Element( i );
|
next:= guard( unitavailabilities.Element( i + 1 ), null( UnitAvailability ) );
|
// if there are more than 1 unitavailability that < start of planning take the last one
|
skip := current.Start() < startofplanning and not isnull( next ) and next.Start() <= startofplanning;
|
if ( not skip )
|
{
|
start := maxvalue( startofplanning, current.Start() );
|
end := minvalue( endofplanning, guard( next.Start(), endofplanning ) );
|
this.AddMinimumProjectedResourceUtilizationExport( resource.Name(), libsciscenario.Name(), start, end, current.MinimumLoadThreshold() );
|
}
|
i := i+1;
|
}
|
}
|
traverse( macroplan, Period_MP, p, not p.IsHistorical() )
|
{
|
sdips := selectset( p, ProductInStockingPointInPeriod.SalesDemandInPeriodBase, sdip, not sdip.istype( DisaggregatedSalesDemandInPeriod ) );
|
salessegments := selectset( sdips, Elements.AsPlanningSalesDemandInPeriod.SalesSegment_MP, ss, true );
|
|
traverse( sdips, Elements.AsSalesDemandInPeriodBase, pispip )
|
{
|
traverse( salessegments, Elements, ss )
|
{
|
quantity := 0.0;
|
fulfilledQuantity := 0.0;
|
revenueQuantity := 0.0;
|
revenueFulfilled := 0.0;
|
hasdata := false;
|
|
traverse( pispip, SalesDemandInPeriodBase, sdipb, sdipb.SalesSegmentName() = ss.Name() and not sdipb.istype( DisaggregatedSalesDemandInPeriod ) )
|
{
|
quantity := quantity + sdipb.Quantity();
|
fulfilledQuantity := fulfilledQuantity + sdipb.FulfilledQuantity();
|
revenueQuantity := revenueQuantity + sdipb.Quantity() * sdipb.BasePricePerQuantity();
|
revenueFulfilled := revenueFulfilled + sdipb.FulfilledQuantity() * sdipb.BasePricePerQuantity();
|
hasdata := true;
|
}
|
|
if( hasdata )
|
{
|
// SalesDemandInPeriod -> ConstrainedDemand
|
libsci.AddConstrainedDemandForExport( libsciscenario.Uri(), pispip.ProductInStockingPoint_MP().ProductID(), pispip.ProductInStockingPoint_MP().StockingPointID(), ss.Name(), p.StartDate(), p.EndDate(), fulfilledQuantity, revenueFulfilled );
|
// SalesDemandInPeriod -> UnconstrainedDemand
|
libsci.AddUnconstrainedDemandForExport( libsciscenario.Uri(), pispip.ProductInStockingPoint_MP().ProductID(), pispip.ProductInStockingPoint_MP().StockingPointID(), ss.Name(), p.StartDate(), p.EndDate(), quantity, revenueQuantity );
|
}
|
}
|
}
|
}// end of not period IsHistorical
|
|
// PlannedInventoryLevel
|
traverse( pisphasiventorylevelend, Elements.ProductInStockingPointInPeriod.astype( ProductInStockingPointInPeriodPlanningLeaf ), pispip, not pispip.Period_MP().IsHistorical() )
|
{
|
pisp := pispip.ProductInStockingPoint_MP();
|
item := pisp.Product_MP().Name();
|
stocklocation := pisp.StockingPoint_MP().Name();
|
libsci.AddPlannedInventoryLevelForExport( libsciscenario.Name(), item, stocklocation, pispip.Period_MP().Start(), pispip.Period_MP().End(), pispip.InventoryLevelEnd() );
|
}
|
// SafetyStocks for both historical and future
|
pispips := selectsortedset( safetystocks, Elements.ProductInStockingPoint_MP.ProductInStockingPointInPeriod.astype( ProductInStockingPointInPeriodPlanningLeaf ),
|
pispip, pispip.ProductInStockingPoint_MP().ProductID(), pispip.ProductInStockingPoint_MP().StockingPointID(), pispip.Start() );
|
traverse( pispips, Elements, pispip )
|
{
|
pisp := pispip.ProductInStockingPoint_MP();
|
item := pisp.Product_MP().Name();
|
stocklocation := pisp.StockingPoint_MP().Name();
|
period := pispip.Period_MP();
|
scenario := ifexpr( period.IsHistorical(), LibSCIIntegration_Utility::SCI_CurrentSOPPlan(), libsciscenario.Name() );
|
appliedmetric := ifexpr( period.IsHistorical(), LibSCIIntegration_Utility::SCI_Metric_ActualInventoryLevel(), LibSCIIntegration_Utility::SCI_Metric_PlannedInventoryLevel() );
|
addtoreport := period.IsHistorical() and libsciscenario.IsCurrent() or not period.IsHistorical();
|
|
if ( addtoreport )
|
{
|
this.AddSafetyStockLevelForExport( scenario, appliedmetric, item, stocklocation, pispip.Period_MP().Start(), pispip.Period_MP().End(), pispip.TargetInventoryLevel() );
|
}
|
}// SafetyStocks Level
|
|
// Export of future InventoryValue
|
inventoryvalues := selectsortedset( macroplan, Product_MP.InventoryValueAndCost, inv,
|
inv.End().DateTime() > startofplanning,
|
inv.ProductID(), inv.StockingPointID(), inv.Start() )
|
this.AddInventoryValue( libsciscenario.Name(), macroplan, inventoryvalues, false );
|
|
inventorytargets := selectsortedset( macroplan, Product_MP.InventorySpecification, it,
|
it.HasMaxLevel() and not it.HasMaxLevelInDays()
|
and ( it.Start().DateTime() >= startofplanning
|
or ( it.Start().DateTime() < startofplanning
|
and guard( it.NextInventorySpecification().Start().DateTime(), macroplan.End() ) > startofplanning ) ),
|
it.Start(), it.ProductID(), it.StockingPointID() );
|
this.AddMaximumInventoryValue( libsciscenario, macroplan, inventorytargets, false );
|
|
|
}
|
}
|
|
|
return m;
|
*]
|
}
|