From 14b9c9168f5e1b2580806aaa96966b5c46805c21 Mon Sep 17 00:00:00 2001
From: yanyuan <yuan.yan@capgemini.com>
Date: 星期四, 07 九月 2023 14:55:05 +0800
Subject: [PATCH] Combine code of MPsync

---
 _Main/BL/Type_MPSync/Method_MappingOperationData.qbl                                                                           |  102 ++
 _Main/UI/MacroPlanner/Component_LanesDataTestDialog/Component_Toolbar458.def                                                   |   70 +
 _Main/BL/Type_MPSync/Method_ImportDBDataCustom.qbl                                                                             |   91 +
 _Main/UI/MacroPlanner/Component_StockpointDataTestDialog/Method_OpenDialog.def                                                 |   17 
 _Main/UI/MacroPlanner/Component_CurrencyDataTestDialog/Response_Toolbar484_btnCancel_OnClick.def                               |   11 
 _Main/UI/MacroPlanner/Component_CurrencyDataTestDialog/Response_Toolbar484_btnOk_OnClick.def                                   |   12 
 _Main/UI/MacroPlanner/Component_StockpointDataTestDialog/Response_Toolbar309_btnCancel_OnClick.def                             |   11 
 _Main/BL/Type_MPSync/Method_MappingLaneData.qbl                                                                                |   16 
 _Main/BL/Type_MPSync/Method_MappingOperationBOMData.qbl                                                                        |  181 +++
 _Main/BL/Type_IOCurrencyRate_MP/StaticMethod_DeleteIfExist.qbl                                                                 |   18 
 _Main/UI/MacroPlanner/Component_StockpointDataTestDialog/_ROOT_Component_StockpointDataTestDialog.def                          |   55 +
 _Main/BL/Type_MPSync/Method_MappingCurrencyData#670.qbl                                                                        |   23 
 _Main/UI/MacroPlanner/Component_CurrencyRateDataTestDialog/Response_Toolbar868_btnCancel_OnClick.def                           |   11 
 _Main/BL/Type_MPSync/Method_MappingUnitData.qbl                                                                                |   52 +
 _Main/BL/Relations/Relation_MappingProduct_MPSync_MPSync_MappingProduct.qbl                                                    |   23 
 _Main/BL/Type_IOLane/StaticMethod_DeleteIfExist.qbl                                                                            |   16 
 _Main/BL/Type_MPSync/Method_MappingForecastData.qbl                                                                            |   40 
 _Main/BL/Type_MacroPlan/StaticMethod_DoSyncNew#821.qbl                                                                         |   17 
 _Main/BL/Type_MPSync/Method_MappingActualPISPIPData.qbl                                                                        |   30 
 _Main/BL/Type_IOLane/_ROOT_Type_IOLane.qbl                                                                                     |    6 
 _var/_Main/KBs/MacroPlanner/ScenarioManager/KB/1.0.0.0/Table_BusinessTypes_1.xml                                               |   11 
 _var/_Main/Data/.keep                                                                                                          |    0 
 _Main/UI/MacroPlanner/Component_CurrencyRateDataTestDialog/_ROOT_Component_CurrencyRateDataTestDialog.def                      |   54 +
 _Main/UI/MacroPlanner/Component_LanesDataTestDialog/_ROOT_Component_LanesDataTestDialog.def                                    |   55 +
 _Main/BL/Type_MPSync/Method_MappingCurrencyData.qbl                                                                            |   17 
 _Main/BL/Type_MPSync/StaticMethod_ApiResponesCheck.qbl                                                                         |   54 +
 _Main/BL/Relations/Relation_MappingExternalSupply_MPSync_MPSync_MappingExternalSupply.qbl                                      |   23 
 _Main/BL/Relations/Relation_MappingBaseConversionFactor_MPSync_MPSync_MappingBaseConversionFact.qbl                            |   23 
 _Main/BL/Relations/Relation_MappingSalesSegment_MPSync_MPSync_MappingSalesSegment.qbl                                          |   23 
 _Main/UI/MacroPlanner/Component_CurrencyDataTestDialog/_ROOT_Component_CurrencyDataTestDialog.def                              |   55 +
 _Main/UI/MacroPlanner/Component_LanesLegsDataTestDialog/Response_Toolbar886_btnOk_OnClick.def                                  |   12 
 _Main/BL/Type_MPSync/Method_MappingCurrencyRateData.qbl                                                                        |   17 
 _Main/UI/MacroPlanner/Component_LanesLegsDataTestDialog/_ROOT_Component_LanesLegsDataTestDialog.def                            |   54 +
 _Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Response_MacroPlanner_mbMainMenu_MenuTestCurrency_OnClick.def       |   13 
 _Main/BL/Type_IOUnit/StaticMethod_FindById.qbl                                                                                 |   14 
 _Main/UI/MacroPlanner/Component_LanesLegsDataTestDialog/Method_OpenDialog.def                                                  |   17 
 _Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Response_MacroPlanner_mbMainMenu_MenuTestLanesLegsData_OnClick.def  |   13 
 _Main/UI/MacroPlanner/Component_LanesLegsDataTestDialog/Response_Toolbar886_btnCancel_OnClick.def                              |   11 
 _Main/BL/Relations/Relation_MappingCustomerOrder_MPSync_MPSync_MappingCustomerOrder.qbl                                        |   23 
 _Main/UI/MacroPlanner/Component_CurrencyRateDataTestDialog/Component_Toolbar868.def                                            |   70 +
 _Main/BL/Type_MPSync/Method_GetProductTypeByProductId.qbl                                                                      |   17 
 _var/_Main/KBs/MacroPlanner/ScenarioManager/KB/1.0.0.0/Change_1086.kbc                                                         |   76 +
 _Main/BL/Type_IOUnitOfMeasure_MP/StaticMethod_DeleteIfExist.qbl                                                                |   17 
 _Main/BL/Type_MPSync/Method_MappingInventoryValueAndCostData.qbl                                                               |   19 
 _Main/UI/MacroPlanner/Component_CurrencyRateDataTestDialog/Method_OpenDialog.def                                               |   17 
 _Main/UI/MacroPlanner/Component_StockpointDataTestDialog/Response_Toolbar309_btnOk_OnClick.def                                 |   12 
 _Main/BL/Type_IOBaseConversionFactor/_ROOT_Type_IOBaseConversionFactor.qbl                                                     |    6 
 _Main/BL/Type_IOOperation/_ROOT_Type_IOOperation.qbl                                                                           |    6 
 _Main/UI/MacroPlanner/Component_CurrencyDataTestDialog/Method_OpenDialog.def                                                   |   17 
 _Main/BL/Type_MPSync/Method_MappingStockingPointData.qbl                                                                       |   16 
 _Main/BL/Type_IOCurrency_MP/_ROOT_Type_IOCurrency_MP.qbl                                                                       |    6 
 _Main/BL/Type_MPSync/Method_MappingLaneLegData.qbl                                                                             |   16 
 _Main/BL/Relations/Relation_MappingProductInLane_MPSync_MPSync_MappingProductInLane.qbl                                        |   23 
 _Main/BL/Type_MPSync/Method_MappingStockingPointData#321.qbl                                                                   |   29 
 _Main/UI/MacroPlanner/Component_CurrencyDataTestDialog/Component_Toolbar484.def                                                |   70 +
 _Main/BL/Type_MPSync/Method_MappingOperationCostData.qbl                                                                       |   55 +
 _Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Response_MacroPlanner_mbMainMenu_MenuTestLanesData_OnClick.def      |   13 
 _Main/BL/Type_IOOperation/StaticMethod_CreateIfNotExist.qbl                                                                    |   18 
 _Main/UI/MacroPlanner/Component_CurrencyRateDataTestDialog/Response_Toolbar868_btnOk_OnClick.def                               |   12 
 _Main/BL/Type_MPSync/Method_MappingProductData.qbl                                                                             |   47 +
 _Main/BL/Relations/Relation_MappingInventoryValueAndCost_MPSync_MPSync_MappingInventoryValueAnd.qbl                            |   23 
 _Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Response_MacroPlanner_mbMainMenu_MenuTestStockpointData_OnClick.def |   13 
 _Main/BL/Type_MPSync/StaticMethod_ApiBuildPostRequestBody.qbl                                                                  |   25 
 _Main/BL/Relations/Relation_MappingActualPISPIP_MPSync_MPSync_MappingActualPISPIP.qbl                                          |   23 
 _Main/BL/Relations/Relation_MappingOperationCost_MPSync_MPSync_MappingOperationCost.qbl                                        |   23 
 _Main/BL/Type_MPSync/Method_MappingExternalSupplyData.qbl                                                                      |   34 
 _Main/BL/Type_MPSync/Method_MappingLaneData#474.qbl                                                                            |   23 
 _Main/BL/Type_MacroPlan/StaticMethod_DoSyncNew#331.qbl                                                                         |   21 
 _Main/BL/Type_IOUnit/_ROOT_Type_IOUnit.qbl                                                                                     |    6 
 _Main/BL/Type_MPSync/_ROOT_Type_MPSync.qbl                                                                                     |    6 
 _Main/BL/Type_MPSync/Method_MappingCustomerOrderData.qbl                                                                       |   44 
 _Main/UI/MacroPlanner/Component_LanesDataTestDialog/Method_OpenDialog.def                                                      |   17 
 _Main/BL/Type_IOProduct_MP/StaticMethod_CreateIfNotExist.qbl                                                                   |   23 
 _Main/BL/Type_IOBaseConversionFactor/StaticMethod_DeleteIfExist.qbl                                                            |   19 
 _Main/BL/Type_MPSync/Method_MappingSalesSegmentData.qbl                                                                        |   23 
 _Main/BL/Type_MPSync/Method_MappingCurencyRatesData.qbl                                                                        |   28 
 _Main/BL/Type_IOUnit/StaticMethod_CreateIfNotExistByTree.qbl                                                                   |   32 
 _Main/UI/MacroPlanner/Component_LanesDataTestDialog/Response_Toolbar458_btnOk_OnClick.def                                      |   12 
 _Main/BL/Type_MacroPlan/StaticMethod_DoSyncNew.qbl                                                                             |   17 
 _Main/BL/Type_IORoutingStep/_ROOT_Type_IORoutingStep.qbl                                                                       |    6 
 _Main/BL/Type_IOProduct_MP/StaticMethod_FindById.qbl                                                                           |   14 
 _var/_Main/KBs/MacroPlanner/ScenarioManager/KB/1.0.0.0/Table_BusinessTypes_1.elm                                               |   10 
 _Main/BL/Relations/Relation_MappingUnit_MPSync_MPSync_MappingUnit.qbl                                                          |   23 
 _Main/BL/Relations/Relation_MappingBOM_MPSync_MPSync_MappingBOM.qbl                                                            |   23 
 _Main/UI/MacroPlanner/Component_LanesDataTestDialog/Response_Toolbar458_btnCancel_OnClick.def                                  |   11 
 _Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Response_MacroPlanner_mbMainMenu_MenuTestCurrencyData_OnClick.def   |   13 
 _Main/BL/Type_MPSync/Method_MappingProductInLaneData.qbl                                                                       |   15 
 _Main/BL/Type_MPSync/Method_MappingUnitOfMeasureData.qbl                                                                       |   14 
 _Main/BL/Relations/Relation_MappingUnitOfMeasure_MPSync_MPSync_MappingUnitOfMeasure.qbl                                        |   23 
 _Main/UI/MacroPlanner/Component_LanesLegsDataTestDialog/Component_Toolbar886.def                                               |   70 +
 _Main/BL/Relations/Relation_MappingForecast_MPSync_MPSync_MappingForecast.qbl                                                  |   23 
 _Main/UI/MacroPlanner/Component_StockpointDataTestDialog/Component_Toolbar309.def                                              |   70 +
 _Main/BL/Type_IOProduct_MP/_ROOT_Type_IOProduct_MP.qbl                                                                         |    6 
 _Main/BL/Type_MPSync/Method_MappingBaseConversionFactorData.qbl                                                                |   19 
 _Main/BL/Type_IOCurrency_MP/StaticMethod_DeleteIfExist.qbl                                                                     |   16 
 _Main/BL/Type_IORoutingStep/StaticMethod_CreateIfNotExist.qbl                                                                  |   22 
 _Main/BL/Type_IOCurrencyRate_MP/_ROOT_Type_IOCurrencyRate_MP.qbl                                                               |    6 
 _Main/BL/Type_MPSync/Method_MappingLaneLegData#257.qbl                                                                         |   30 
 _Main/BL/Relations/Relation_MappingOperation_MPSync_MPSync_MappingOperation.qbl                                                |   23 
 _Main/BL/Type_MPSync/Method_MappingSalesLevelData.qbl                                                                          |   18 
 100 files changed, 2,720 insertions(+), 0 deletions(-)

diff --git a/_Main/BL/Relations/Relation_MappingActualPISPIP_MPSync_MPSync_MappingActualPISPIP.qbl b/_Main/BL/Relations/Relation_MappingActualPISPIP_MPSync_MPSync_MappingActualPISPIP.qbl
new file mode 100644
index 0000000..0f7a1ec
--- /dev/null
+++ b/_Main/BL/Relations/Relation_MappingActualPISPIP_MPSync_MPSync_MappingActualPISPIP.qbl
@@ -0,0 +1,23 @@
+Quintiq file version 2.0
+#parent: #root
+Relation MappingActualPISPIP_MPSync_MPSync_MappingActualPISPIP
+{
+  #keys: '1[414384.0.737300004]'
+  DefaultRelationStrategy
+  {
+  }
+  RelationSide.LeftSide MPSync
+  {
+    #keys: '3[414384.0.737300006][414384.0.737300005][414384.0.737300007]'
+    Cardinality: '0to1'
+    ObjectDefinition: MappingActualPISPIP
+    OwningSide: 'Reference'
+  }
+  RelationSide.RightSide MappingActualPISPIP
+  {
+    #keys: '3[414384.0.737300009][414384.0.737300008][414384.0.737300010]'
+    Cardinality: '1toN'
+    ObjectDefinition: MPSync
+    OwningSide: 'Owned'
+  }
+}
diff --git a/_Main/BL/Relations/Relation_MappingBOM_MPSync_MPSync_MappingBOM.qbl b/_Main/BL/Relations/Relation_MappingBOM_MPSync_MPSync_MappingBOM.qbl
new file mode 100644
index 0000000..0af0e9d
--- /dev/null
+++ b/_Main/BL/Relations/Relation_MappingBOM_MPSync_MPSync_MappingBOM.qbl
@@ -0,0 +1,23 @@
+Quintiq file version 2.0
+#parent: #root
+Relation MappingBOM_MPSync_MPSync_MappingBOM
+{
+  #keys: '1[414384.0.737300037]'
+  DefaultRelationStrategy
+  {
+  }
+  RelationSide.LeftSide MPSync
+  {
+    #keys: '3[414384.0.737300039][414384.0.737300038][414384.0.737300040]'
+    Cardinality: '0to1'
+    ObjectDefinition: MappingBOM
+    OwningSide: 'Reference'
+  }
+  RelationSide.RightSide MappingBOM
+  {
+    #keys: '3[414384.0.737300042][414384.0.737300041][414384.0.737300043]'
+    Cardinality: '1toN'
+    ObjectDefinition: MPSync
+    OwningSide: 'Owned'
+  }
+}
diff --git a/_Main/BL/Relations/Relation_MappingBaseConversionFactor_MPSync_MPSync_MappingBaseConversionFact.qbl b/_Main/BL/Relations/Relation_MappingBaseConversionFactor_MPSync_MPSync_MappingBaseConversionFact.qbl
new file mode 100644
index 0000000..d038edc
--- /dev/null
+++ b/_Main/BL/Relations/Relation_MappingBaseConversionFactor_MPSync_MPSync_MappingBaseConversionFact.qbl
@@ -0,0 +1,23 @@
+Quintiq file version 2.0
+#parent: #root
+Relation MappingBaseConversionFactor_MPSync_MPSync_MappingBaseConversionFactor
+{
+  #keys: '1[414384.0.737300021]'
+  DefaultRelationStrategy
+  {
+  }
+  RelationSide.LeftSide MPSync
+  {
+    #keys: '3[414384.0.737300023][414384.0.737300022][414384.0.737300024]'
+    Cardinality: '0to1'
+    ObjectDefinition: MappingBaseConversionFactor
+    OwningSide: 'Reference'
+  }
+  RelationSide.RightSide MappingBaseConversionFactor
+  {
+    #keys: '3[414384.0.737300026][414384.0.737300025][414384.0.737300027]'
+    Cardinality: '1toN'
+    ObjectDefinition: MPSync
+    OwningSide: 'Owned'
+  }
+}
diff --git a/_Main/BL/Relations/Relation_MappingCustomerOrder_MPSync_MPSync_MappingCustomerOrder.qbl b/_Main/BL/Relations/Relation_MappingCustomerOrder_MPSync_MPSync_MappingCustomerOrder.qbl
new file mode 100644
index 0000000..0b61f30
--- /dev/null
+++ b/_Main/BL/Relations/Relation_MappingCustomerOrder_MPSync_MPSync_MappingCustomerOrder.qbl
@@ -0,0 +1,23 @@
+Quintiq file version 2.0
+#parent: #root
+Relation MappingCustomerOrder_MPSync_MPSync_MappingCustomerOrder
+{
+  #keys: '1[414384.0.737300053]'
+  DefaultRelationStrategy
+  {
+  }
+  RelationSide.LeftSide MPSync
+  {
+    #keys: '3[414384.0.737300055][414384.0.737300054][414384.0.737300056]'
+    Cardinality: '0to1'
+    ObjectDefinition: MappingCustomerOrder
+    OwningSide: 'Reference'
+  }
+  RelationSide.RightSide MappingCustomerOrder
+  {
+    #keys: '3[414384.0.737300058][414384.0.737300057][414384.0.737300059]'
+    Cardinality: '1toN'
+    ObjectDefinition: MPSync
+    OwningSide: 'Owned'
+  }
+}
diff --git a/_Main/BL/Relations/Relation_MappingExternalSupply_MPSync_MPSync_MappingExternalSupply.qbl b/_Main/BL/Relations/Relation_MappingExternalSupply_MPSync_MPSync_MappingExternalSupply.qbl
new file mode 100644
index 0000000..a4fbde1
--- /dev/null
+++ b/_Main/BL/Relations/Relation_MappingExternalSupply_MPSync_MPSync_MappingExternalSupply.qbl
@@ -0,0 +1,23 @@
+Quintiq file version 2.0
+#parent: #root
+Relation MappingExternalSupply_MPSync_MPSync_MappingExternalSupply
+{
+  #keys: '1[414384.0.737300069]'
+  DefaultRelationStrategy
+  {
+  }
+  RelationSide.LeftSide MPSync
+  {
+    #keys: '3[414384.0.737300071][414384.0.737300070][414384.0.737300072]'
+    Cardinality: '0to1'
+    ObjectDefinition: MappingExternalSupply
+    OwningSide: 'Reference'
+  }
+  RelationSide.RightSide MappingExternalSupply
+  {
+    #keys: '3[414384.0.737300074][414384.0.737300073][414384.0.737300075]'
+    Cardinality: '1toN'
+    ObjectDefinition: MPSync
+    OwningSide: 'Owned'
+  }
+}
diff --git a/_Main/BL/Relations/Relation_MappingForecast_MPSync_MPSync_MappingForecast.qbl b/_Main/BL/Relations/Relation_MappingForecast_MPSync_MPSync_MappingForecast.qbl
new file mode 100644
index 0000000..d90edf7
--- /dev/null
+++ b/_Main/BL/Relations/Relation_MappingForecast_MPSync_MPSync_MappingForecast.qbl
@@ -0,0 +1,23 @@
+Quintiq file version 2.0
+#parent: #root
+Relation MappingForecast_MPSync_MPSync_MappingForecast
+{
+  #keys: '1[414384.0.737300085]'
+  DefaultRelationStrategy
+  {
+  }
+  RelationSide.LeftSide MPSync
+  {
+    #keys: '3[414384.0.737300087][414384.0.737300086][414384.0.737300088]'
+    Cardinality: '0to1'
+    ObjectDefinition: MappingForecast
+    OwningSide: 'Reference'
+  }
+  RelationSide.RightSide MappingForecast
+  {
+    #keys: '3[414384.0.737300090][414384.0.737300089][414384.0.737300091]'
+    Cardinality: '1toN'
+    ObjectDefinition: MPSync
+    OwningSide: 'Owned'
+  }
+}
diff --git a/_Main/BL/Relations/Relation_MappingInventoryValueAndCost_MPSync_MPSync_MappingInventoryValueAnd.qbl b/_Main/BL/Relations/Relation_MappingInventoryValueAndCost_MPSync_MPSync_MappingInventoryValueAnd.qbl
new file mode 100644
index 0000000..9f91cf9
--- /dev/null
+++ b/_Main/BL/Relations/Relation_MappingInventoryValueAndCost_MPSync_MPSync_MappingInventoryValueAnd.qbl
@@ -0,0 +1,23 @@
+Quintiq file version 2.0
+#parent: #root
+Relation MappingInventoryValueAndCost_MPSync_MPSync_MappingInventoryValueAndCost
+{
+  #keys: '1[414384.0.737300101]'
+  DefaultRelationStrategy
+  {
+  }
+  RelationSide.LeftSide MPSync
+  {
+    #keys: '3[414384.0.737300103][414384.0.737300102][414384.0.737300104]'
+    Cardinality: '0to1'
+    ObjectDefinition: MappingInventoryValueAndCost
+    OwningSide: 'Reference'
+  }
+  RelationSide.RightSide MappingInventoryValueAndCost
+  {
+    #keys: '3[414384.0.737300106][414384.0.737300105][414384.0.737300107]'
+    Cardinality: '1toN'
+    ObjectDefinition: MPSync
+    OwningSide: 'Owned'
+  }
+}
diff --git a/_Main/BL/Relations/Relation_MappingOperationCost_MPSync_MPSync_MappingOperationCost.qbl b/_Main/BL/Relations/Relation_MappingOperationCost_MPSync_MPSync_MappingOperationCost.qbl
new file mode 100644
index 0000000..67b9f81
--- /dev/null
+++ b/_Main/BL/Relations/Relation_MappingOperationCost_MPSync_MPSync_MappingOperationCost.qbl
@@ -0,0 +1,23 @@
+Quintiq file version 2.0
+#parent: #root
+Relation MappingOperationCost_MPSync_MPSync_MappingOperationCost
+{
+  #keys: '1[414384.0.736080617]'
+  DefaultRelationStrategy
+  {
+  }
+  RelationSide.LeftSide MPSync
+  {
+    #keys: '3[414384.0.736080619][414384.0.736080618][414384.0.736080620]'
+    Cardinality: '0to1'
+    ObjectDefinition: MappingOperationCost
+    OwningSide: 'Reference'
+  }
+  RelationSide.RightSide MappingOperationCost
+  {
+    #keys: '3[414384.0.736080622][414384.0.736080621][414384.0.736080623]'
+    Cardinality: '1toN'
+    ObjectDefinition: MPSync
+    OwningSide: 'Owned'
+  }
+}
diff --git a/_Main/BL/Relations/Relation_MappingOperation_MPSync_MPSync_MappingOperation.qbl b/_Main/BL/Relations/Relation_MappingOperation_MPSync_MPSync_MappingOperation.qbl
new file mode 100644
index 0000000..bb6553e
--- /dev/null
+++ b/_Main/BL/Relations/Relation_MappingOperation_MPSync_MPSync_MappingOperation.qbl
@@ -0,0 +1,23 @@
+Quintiq file version 2.0
+#parent: #root
+Relation MappingOperation_MPSync_MPSync_MappingOperation
+{
+  #keys: '1[414384.0.737300117]'
+  DefaultRelationStrategy
+  {
+  }
+  RelationSide.LeftSide MPSync
+  {
+    #keys: '3[414384.0.737300119][414384.0.737300118][414384.0.737300120]'
+    Cardinality: '0to1'
+    ObjectDefinition: MappingOperation
+    OwningSide: 'Reference'
+  }
+  RelationSide.RightSide MappingOperation
+  {
+    #keys: '3[414384.0.737300122][414384.0.737300121][414384.0.737300123]'
+    Cardinality: '1toN'
+    ObjectDefinition: MPSync
+    OwningSide: 'Owned'
+  }
+}
diff --git a/_Main/BL/Relations/Relation_MappingProductInLane_MPSync_MPSync_MappingProductInLane.qbl b/_Main/BL/Relations/Relation_MappingProductInLane_MPSync_MPSync_MappingProductInLane.qbl
new file mode 100644
index 0000000..a8def35
--- /dev/null
+++ b/_Main/BL/Relations/Relation_MappingProductInLane_MPSync_MPSync_MappingProductInLane.qbl
@@ -0,0 +1,23 @@
+Quintiq file version 2.0
+#parent: #root
+Relation MappingProductInLane_MPSync_MPSync_MappingProductInLane
+{
+  #keys: '1[414384.0.736080646]'
+  DefaultRelationStrategy
+  {
+  }
+  RelationSide.LeftSide MPSync
+  {
+    #keys: '3[414384.0.736080648][414384.0.736080647][414384.0.736080649]'
+    Cardinality: '0to1'
+    ObjectDefinition: MappingProductInLane
+    OwningSide: 'Reference'
+  }
+  RelationSide.RightSide MappingProductInLane
+  {
+    #keys: '3[414384.0.736080651][414384.0.736080650][414384.0.736080652]'
+    Cardinality: '1toN'
+    ObjectDefinition: MPSync
+    OwningSide: 'Owned'
+  }
+}
diff --git a/_Main/BL/Relations/Relation_MappingProduct_MPSync_MPSync_MappingProduct.qbl b/_Main/BL/Relations/Relation_MappingProduct_MPSync_MPSync_MappingProduct.qbl
new file mode 100644
index 0000000..64c3aef
--- /dev/null
+++ b/_Main/BL/Relations/Relation_MappingProduct_MPSync_MPSync_MappingProduct.qbl
@@ -0,0 +1,23 @@
+Quintiq file version 2.0
+#parent: #root
+Relation MappingProduct_MPSync_MPSync_MappingProduct
+{
+  #keys: '1[414384.0.736080633]'
+  DefaultRelationStrategy
+  {
+  }
+  RelationSide.LeftSide MPSync
+  {
+    #keys: '3[414384.0.736080635][414384.0.736080634][414384.0.736080636]'
+    Cardinality: '0to1'
+    ObjectDefinition: MappingProduct
+    OwningSide: 'Reference'
+  }
+  RelationSide.RightSide MappingProduct
+  {
+    #keys: '3[414384.0.736080638][414384.0.736080637][414384.0.736080639]'
+    Cardinality: '1toN'
+    ObjectDefinition: MPSync
+    OwningSide: 'Owned'
+  }
+}
diff --git a/_Main/BL/Relations/Relation_MappingSalesSegment_MPSync_MPSync_MappingSalesSegment.qbl b/_Main/BL/Relations/Relation_MappingSalesSegment_MPSync_MPSync_MappingSalesSegment.qbl
new file mode 100644
index 0000000..7af3e26
--- /dev/null
+++ b/_Main/BL/Relations/Relation_MappingSalesSegment_MPSync_MPSync_MappingSalesSegment.qbl
@@ -0,0 +1,23 @@
+Quintiq file version 2.0
+#parent: #root
+Relation MappingSalesSegment_MPSync_MPSync_MappingSalesSegment
+{
+  #keys: '1[414384.0.736080662]'
+  DefaultRelationStrategy
+  {
+  }
+  RelationSide.LeftSide MPSync
+  {
+    #keys: '3[414384.0.736080664][414384.0.736080663][414384.0.736080665]'
+    Cardinality: '0to1'
+    ObjectDefinition: MappingSalesSegment
+    OwningSide: 'Reference'
+  }
+  RelationSide.RightSide MappingSalesSegment
+  {
+    #keys: '3[414384.0.736080667][414384.0.736080666][414384.0.736080668]'
+    Cardinality: '1toN'
+    ObjectDefinition: MPSync
+    OwningSide: 'Owned'
+  }
+}
diff --git a/_Main/BL/Relations/Relation_MappingUnitOfMeasure_MPSync_MPSync_MappingUnitOfMeasure.qbl b/_Main/BL/Relations/Relation_MappingUnitOfMeasure_MPSync_MPSync_MappingUnitOfMeasure.qbl
new file mode 100644
index 0000000..f1c43b5
--- /dev/null
+++ b/_Main/BL/Relations/Relation_MappingUnitOfMeasure_MPSync_MPSync_MappingUnitOfMeasure.qbl
@@ -0,0 +1,23 @@
+Quintiq file version 2.0
+#parent: #root
+Relation MappingUnitOfMeasure_MPSync_MPSync_MappingUnitOfMeasure
+{
+  #keys: '1[414384.0.736080697]'
+  DefaultRelationStrategy
+  {
+  }
+  RelationSide.LeftSide MPSync
+  {
+    #keys: '3[414384.0.736080699][414384.0.736080698][414384.0.736080700]'
+    Cardinality: '0to1'
+    ObjectDefinition: MappingUnitOfMeasure
+    OwningSide: 'Reference'
+  }
+  RelationSide.RightSide MappingUnitOfMeasure
+  {
+    #keys: '3[414384.0.736080702][414384.0.736080701][414384.0.736080703]'
+    Cardinality: '1toN'
+    ObjectDefinition: MPSync
+    OwningSide: 'Owned'
+  }
+}
diff --git a/_Main/BL/Relations/Relation_MappingUnit_MPSync_MPSync_MappingUnit.qbl b/_Main/BL/Relations/Relation_MappingUnit_MPSync_MPSync_MappingUnit.qbl
new file mode 100644
index 0000000..96a13c9
--- /dev/null
+++ b/_Main/BL/Relations/Relation_MappingUnit_MPSync_MPSync_MappingUnit.qbl
@@ -0,0 +1,23 @@
+Quintiq file version 2.0
+#parent: #root
+Relation MappingUnit_MPSync_MPSync_MappingUnit
+{
+  #keys: '1[414384.0.736080678]'
+  DefaultRelationStrategy
+  {
+  }
+  RelationSide.LeftSide MPSync
+  {
+    #keys: '3[414384.0.736080680][414384.0.736080679][414384.0.736080681]'
+    Cardinality: '0to1'
+    ObjectDefinition: MappingUnit
+    OwningSide: 'Reference'
+  }
+  RelationSide.RightSide MappingUnit
+  {
+    #keys: '3[414384.0.736080683][414384.0.736080682][414384.0.736080684]'
+    Cardinality: '1toN'
+    ObjectDefinition: MPSync
+    OwningSide: 'Owned'
+  }
+}
diff --git a/_Main/BL/Type_IOBaseConversionFactor/StaticMethod_DeleteIfExist.qbl b/_Main/BL/Type_IOBaseConversionFactor/StaticMethod_DeleteIfExist.qbl
new file mode 100644
index 0000000..9802666
--- /dev/null
+++ b/_Main/BL/Type_IOBaseConversionFactor/StaticMethod_DeleteIfExist.qbl
@@ -0,0 +1,19 @@
+Quintiq file version 2.0
+#parent: #root
+StaticMethod DeleteIfExist (
+  MPSync mpSync,
+  String from,
+  String to,
+  String productId
+)
+{
+  TextBody:
+  [*
+    // yypsybs Sep-1-2023 (created)
+    toDel := select( mpSync, IOBaseConversionFactor, item, 
+                     item.SourceUnitOfMeasureName() = from and item.TargetUnitOfMeasureName() = to and item.ProductID() = productId );
+    if( not isnull( toDel ) ) {
+      toDel.Delete();  
+    }
+  *]
+}
diff --git a/_Main/BL/Type_IOBaseConversionFactor/_ROOT_Type_IOBaseConversionFactor.qbl b/_Main/BL/Type_IOBaseConversionFactor/_ROOT_Type_IOBaseConversionFactor.qbl
new file mode 100644
index 0000000..6636e3d
--- /dev/null
+++ b/_Main/BL/Type_IOBaseConversionFactor/_ROOT_Type_IOBaseConversionFactor.qbl
@@ -0,0 +1,6 @@
+Quintiq file version 2.0
+#root
+#parent: #DomainModel
+TypeSpecialization IOBaseConversionFactor #extension
+{
+}
diff --git a/_Main/BL/Type_IOCurrencyRate_MP/StaticMethod_DeleteIfExist.qbl b/_Main/BL/Type_IOCurrencyRate_MP/StaticMethod_DeleteIfExist.qbl
new file mode 100644
index 0000000..474e3f5
--- /dev/null
+++ b/_Main/BL/Type_IOCurrencyRate_MP/StaticMethod_DeleteIfExist.qbl
@@ -0,0 +1,18 @@
+Quintiq file version 2.0
+#parent: #root
+StaticMethod DeleteIfExist (
+  MPSync mpSync,
+  String currencyId,
+  Date start
+)
+{
+  TextBody:
+  [*
+    // yypsybs Sep-1-2023 (created)
+    toDel := select( mpSync, IOCurrencyRate_MP, item, 
+                     item.CurrencyID() = currencyId and item.Start() = start );
+    if( not isnull( toDel ) ) {
+      toDel.Delete();  
+    }
+  *]
+}
diff --git a/_Main/BL/Type_IOCurrencyRate_MP/_ROOT_Type_IOCurrencyRate_MP.qbl b/_Main/BL/Type_IOCurrencyRate_MP/_ROOT_Type_IOCurrencyRate_MP.qbl
new file mode 100644
index 0000000..21d526b
--- /dev/null
+++ b/_Main/BL/Type_IOCurrencyRate_MP/_ROOT_Type_IOCurrencyRate_MP.qbl
@@ -0,0 +1,6 @@
+Quintiq file version 2.0
+#root
+#parent: #DomainModel
+TypeSpecialization IOCurrencyRate_MP #extension
+{
+}
diff --git a/_Main/BL/Type_IOCurrency_MP/StaticMethod_DeleteIfExist.qbl b/_Main/BL/Type_IOCurrency_MP/StaticMethod_DeleteIfExist.qbl
new file mode 100644
index 0000000..b476627
--- /dev/null
+++ b/_Main/BL/Type_IOCurrency_MP/StaticMethod_DeleteIfExist.qbl
@@ -0,0 +1,16 @@
+Quintiq file version 2.0
+#parent: #root
+StaticMethod DeleteIfExist (
+  MPSync mpSync,
+  String id
+)
+{
+  TextBody:
+  [*
+    // yypsybs Sep-1-2023 (created)
+    toDel := select( mpSync, IOCurrency_MP, item, item.ID() = id );
+    if( not isnull( toDel ) ) {
+      toDel.Delete();
+    }
+  *]
+}
diff --git a/_Main/BL/Type_IOCurrency_MP/_ROOT_Type_IOCurrency_MP.qbl b/_Main/BL/Type_IOCurrency_MP/_ROOT_Type_IOCurrency_MP.qbl
new file mode 100644
index 0000000..36fb030
--- /dev/null
+++ b/_Main/BL/Type_IOCurrency_MP/_ROOT_Type_IOCurrency_MP.qbl
@@ -0,0 +1,6 @@
+Quintiq file version 2.0
+#root
+#parent: #DomainModel
+TypeSpecialization IOCurrency_MP #extension
+{
+}
diff --git a/_Main/BL/Type_IOLane/StaticMethod_DeleteIfExist.qbl b/_Main/BL/Type_IOLane/StaticMethod_DeleteIfExist.qbl
new file mode 100644
index 0000000..cfd3b35
--- /dev/null
+++ b/_Main/BL/Type_IOLane/StaticMethod_DeleteIfExist.qbl
@@ -0,0 +1,16 @@
+Quintiq file version 2.0
+#parent: #root
+StaticMethod DeleteIfExist (
+  MPSync mpSync,
+  String id
+)
+{
+  TextBody:
+  [*
+    // yypsybs Sep-1-2023 (created)
+    toDel := select( mpSync, IOLane, item, item.ID() = id );
+    if( not isnull( toDel ) ) {
+      toDel.Delete();  
+    }
+  *]
+}
diff --git a/_Main/BL/Type_IOLane/_ROOT_Type_IOLane.qbl b/_Main/BL/Type_IOLane/_ROOT_Type_IOLane.qbl
new file mode 100644
index 0000000..66ac220
--- /dev/null
+++ b/_Main/BL/Type_IOLane/_ROOT_Type_IOLane.qbl
@@ -0,0 +1,6 @@
+Quintiq file version 2.0
+#root
+#parent: #DomainModel
+TypeSpecialization IOLane #extension
+{
+}
diff --git a/_Main/BL/Type_IOOperation/StaticMethod_CreateIfNotExist.qbl b/_Main/BL/Type_IOOperation/StaticMethod_CreateIfNotExist.qbl
new file mode 100644
index 0000000..c6d4e89
--- /dev/null
+++ b/_Main/BL/Type_IOOperation/StaticMethod_CreateIfNotExist.qbl
@@ -0,0 +1,18 @@
+Quintiq file version 2.0
+#parent: #root
+StaticMethod CreateIfNotExist (
+  MPSync mpSync,
+  String id
+) as IOOperation
+{
+  TextBody:
+  [*
+    // yypsybs Sep-5-2023 (created)
+    result := select( mpSync, IOOperation, op, op.ID() = id );
+    if( isnull( result ) ) {
+      result := mpSync.IOOperation( relnew, 
+                          ID := id );
+    }
+    return result;
+  *]
+}
diff --git a/_Main/BL/Type_IOOperation/_ROOT_Type_IOOperation.qbl b/_Main/BL/Type_IOOperation/_ROOT_Type_IOOperation.qbl
new file mode 100644
index 0000000..3bb29a6
--- /dev/null
+++ b/_Main/BL/Type_IOOperation/_ROOT_Type_IOOperation.qbl
@@ -0,0 +1,6 @@
+Quintiq file version 2.0
+#root
+#parent: #DomainModel
+TypeSpecialization IOOperation #extension
+{
+}
diff --git a/_Main/BL/Type_IOProduct_MP/StaticMethod_CreateIfNotExist.qbl b/_Main/BL/Type_IOProduct_MP/StaticMethod_CreateIfNotExist.qbl
new file mode 100644
index 0000000..3a636ab
--- /dev/null
+++ b/_Main/BL/Type_IOProduct_MP/StaticMethod_CreateIfNotExist.qbl
@@ -0,0 +1,23 @@
+Quintiq file version 2.0
+#parent: #root
+StaticMethod CreateIfNotExist (
+  MPSync mpSync,
+  String id,
+  String name,
+  String parentId,
+  String uom
+) as IOProduct_MP
+{
+  TextBody:
+  [*
+    // yypsybs Sep-1-2023 (created)
+    value := IOProduct_MP::FindById( mpSync, id );
+    if( isnull( value ) ) {
+      value := IOProduct_MP::Create( mpSync, id, name, "", uom );
+      if( parentId <> "" ) {
+        value.ParentID( parentId );
+      }
+    }
+    return value;
+  *]
+}
diff --git a/_Main/BL/Type_IOProduct_MP/StaticMethod_FindById.qbl b/_Main/BL/Type_IOProduct_MP/StaticMethod_FindById.qbl
new file mode 100644
index 0000000..b080495
--- /dev/null
+++ b/_Main/BL/Type_IOProduct_MP/StaticMethod_FindById.qbl
@@ -0,0 +1,14 @@
+Quintiq file version 2.0
+#parent: #root
+StaticMethod FindById (
+  MPSync mpSync,
+  String id
+) as IOProduct_MP
+{
+  TextBody:
+  [*
+    // yypsybs Sep-1-2023 (created)
+    result := select( mpSync, IOProduct_MP, item, item.ID() = id );
+    return result;
+  *]
+}
diff --git a/_Main/BL/Type_IOProduct_MP/_ROOT_Type_IOProduct_MP.qbl b/_Main/BL/Type_IOProduct_MP/_ROOT_Type_IOProduct_MP.qbl
new file mode 100644
index 0000000..e99d7ea
--- /dev/null
+++ b/_Main/BL/Type_IOProduct_MP/_ROOT_Type_IOProduct_MP.qbl
@@ -0,0 +1,6 @@
+Quintiq file version 2.0
+#root
+#parent: #DomainModel
+TypeSpecialization IOProduct_MP #extension
+{
+}
diff --git a/_Main/BL/Type_IORoutingStep/StaticMethod_CreateIfNotExist.qbl b/_Main/BL/Type_IORoutingStep/StaticMethod_CreateIfNotExist.qbl
new file mode 100644
index 0000000..e5e10b1
--- /dev/null
+++ b/_Main/BL/Type_IORoutingStep/StaticMethod_CreateIfNotExist.qbl
@@ -0,0 +1,22 @@
+Quintiq file version 2.0
+#parent: #root
+StaticMethod CreateIfNotExist (
+  MPSync mpSync,
+  String routingId,
+  String name,
+  Number seq
+) as IORoutingStep
+{
+  TextBody:
+  [*
+    // yypsybs Sep-5-2023 (created)
+    value := select( mpSync, IORoutingStep, item, item.RoutingID() = routingId and item.Name() = name and item.SequenceNumberForExcel() = seq );
+    if( isnull( value ) ) {
+      mpSync.IORoutingStep( relnew, 
+                            RoutingID := routingId, 
+                            Name := name, 
+                            SequenceNumberForExcel := seq  );
+    }
+    return value;
+  *]
+}
diff --git a/_Main/BL/Type_IORoutingStep/_ROOT_Type_IORoutingStep.qbl b/_Main/BL/Type_IORoutingStep/_ROOT_Type_IORoutingStep.qbl
new file mode 100644
index 0000000..966b160
--- /dev/null
+++ b/_Main/BL/Type_IORoutingStep/_ROOT_Type_IORoutingStep.qbl
@@ -0,0 +1,6 @@
+Quintiq file version 2.0
+#root
+#parent: #DomainModel
+TypeSpecialization IORoutingStep #extension
+{
+}
diff --git a/_Main/BL/Type_IOUnit/StaticMethod_CreateIfNotExistByTree.qbl b/_Main/BL/Type_IOUnit/StaticMethod_CreateIfNotExistByTree.qbl
new file mode 100644
index 0000000..61c9d6b
--- /dev/null
+++ b/_Main/BL/Type_IOUnit/StaticMethod_CreateIfNotExistByTree.qbl
@@ -0,0 +1,32 @@
+Quintiq file version 2.0
+#parent: #root
+StaticMethod CreateIfNotExistByTree (
+  MPSync mpSync,
+  String id,
+  String name,
+  String parentId,
+  String UOMName,
+  String currencyId,
+  Date startDate,
+  Date endDate,
+  String capacityType
+) as IOUnit
+{
+  TextBody:
+  [*
+    // yypsybs Sep-6-2023 (created)
+    value := IOUnit::FindById( mpSync, id );
+    if( isnull( value ) ) {
+      value := mpSync.IOUnit( relnew, 
+                     ID := id,
+                     Name := name, 
+                     ParentUnitID := parentId, 
+                     UnitOfMeasureName := UOMName, 
+                     CurrencyID := currencyId, 
+                     StartDate := startDate, 
+                     EndDate := endDate, 
+                     CapacityType := capacityType );
+    }
+    return value;
+  *]
+}
diff --git a/_Main/BL/Type_IOUnit/StaticMethod_FindById.qbl b/_Main/BL/Type_IOUnit/StaticMethod_FindById.qbl
new file mode 100644
index 0000000..8d1460c
--- /dev/null
+++ b/_Main/BL/Type_IOUnit/StaticMethod_FindById.qbl
@@ -0,0 +1,14 @@
+Quintiq file version 2.0
+#parent: #root
+StaticMethod FindById (
+  MPSync mpSync,
+  String id
+) as IOUnit
+{
+  TextBody:
+  [*
+    // yypsybs Sep-6-2023 (created)
+    value := select( mpSync, IOUnit, item, item.ID() = id );
+    return value;
+  *]
+}
diff --git a/_Main/BL/Type_IOUnit/_ROOT_Type_IOUnit.qbl b/_Main/BL/Type_IOUnit/_ROOT_Type_IOUnit.qbl
new file mode 100644
index 0000000..4056a12
--- /dev/null
+++ b/_Main/BL/Type_IOUnit/_ROOT_Type_IOUnit.qbl
@@ -0,0 +1,6 @@
+Quintiq file version 2.0
+#root
+#parent: #DomainModel
+TypeSpecialization IOUnit #extension
+{
+}
diff --git a/_Main/BL/Type_IOUnitOfMeasure_MP/StaticMethod_DeleteIfExist.qbl b/_Main/BL/Type_IOUnitOfMeasure_MP/StaticMethod_DeleteIfExist.qbl
new file mode 100644
index 0000000..43a9efe
--- /dev/null
+++ b/_Main/BL/Type_IOUnitOfMeasure_MP/StaticMethod_DeleteIfExist.qbl
@@ -0,0 +1,17 @@
+Quintiq file version 2.0
+#parent: #root
+StaticMethod DeleteIfExist (
+  MPSync mpSync,
+  String name
+)
+{
+  TextBody:
+  [*
+    // yypsybs Sep-1-2023 (created)
+    toDel := select( mpSync, IOUnitOfMeasure_MP, item, 
+                     item.Name() = name );
+    if( not isnull( toDel ) ) {
+      toDel.Delete();  
+    }
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/Method_GetProductTypeByProductId.qbl b/_Main/BL/Type_MPSync/Method_GetProductTypeByProductId.qbl
new file mode 100644
index 0000000..7e4e927
--- /dev/null
+++ b/_Main/BL/Type_MPSync/Method_GetProductTypeByProductId.qbl
@@ -0,0 +1,17 @@
+Quintiq file version 2.0
+#parent: #root
+Method GetProductTypeByProductId (
+  String productId
+) as String
+{
+  TextBody:
+  [*
+    // yypsybs Sep-5-2023 (created)
+    values := selectvalues( this, MappingBOM, item, item.ProductCode() = productId, item.ProductType() );
+    value := "";
+    if( values.Size() > 0 ) {
+      value := values.Element( 0 );  
+    }
+    return value;
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/Method_ImportDBDataCustom.qbl b/_Main/BL/Type_MPSync/Method_ImportDBDataCustom.qbl
new file mode 100644
index 0000000..0646b5f
--- /dev/null
+++ b/_Main/BL/Type_MPSync/Method_ImportDBDataCustom.qbl
@@ -0,0 +1,91 @@
+Quintiq file version 2.0
+#parent: #root
+Method ImportDBDataCustom (
+  MacroPlan macroPlan,
+  Strings businessTypes,
+  Boolean isKeyProduct,
+  Boolean createPurchaseSupplyMaterial
+)
+{
+  Description: '灏嗚〃鐨勬暟鎹浆涓篒Oxxxx鐨勬暟鎹�'
+  TextBody:
+  [*
+    // Import data from DB
+    
+    // 鏁版嵁澶勭悊
+    
+    // 閿�鍞骇鍒強閿�鍞儴闂�
+    this.MappingSalesLevelData();
+    this.Broker_OTD_SalesSegment().Execute();
+    this.MappingSalesSegmentData( businessTypes );
+    
+    // 鍗曚綅鍙婂崟浣嶆崲绠�
+    this.Broker_OTD_UnitOfMeasure().Execute();
+    this.MappingUnitOfMeasureData();
+    this.Broker_OTD_BaseConversionFactor().Execute();
+    this.MappingBaseConversionFactorData();
+    
+    // 璐у竵鍙婅揣甯佹眹鐜�
+    this.MappingCurrencyData();
+    this.MappingCurrencyRateData();
+    
+    // 搴撳瓨鐐�
+    this.MappingStockingPointData();
+    
+    // 浜у搧
+    this.Broker_OTD_Product().Execute();
+    this.MappingProductData( businessTypes, isKeyProduct );
+    
+    // 璁㈠崟棰勬祴
+    this.Broker_OTD_Forecast().Execute();
+    this.MappingForecastData( businessTypes );
+    
+    // 璁㈠崟闇�姹�
+    this.Broker_OTD_CustomerOrder().Execute();
+    this.MappingCustomerOrderData( businessTypes );
+    
+    // 杞﹂亾
+    this.MappingLaneData();
+    // 杞﹂亾杩愯緭娈�
+    this.MappingLaneLegData();
+    // 渚涘簲缃戠粶锛堣溅閬擄級
+    this.Broker_OTD_ProductInLane().Execute();
+    this.MappingProductInLaneData();
+    
+    // routing routingStep unit operation operationLink operationInputGroup operationBOM
+    this.Broker_OTD_Operation().Execute();
+    this.Broker_OTD_BOM().Execute();
+    // 娓呯悊鏃ф暟鎹�
+    this.IOUnit( relflush );
+    this.IOOperation( relflush );
+    this.IOOperationLink( relflush );
+    this.IOOperationInputGroup( relflush );
+    // 澶勭悊鏁版嵁
+    this.MappingUnitData( businessTypes );
+    this.MappingOperationData( businessTypes );
+    // 娓呯悊鏃ф暟鎹�
+    this.IOOperationBOM( relflush );
+    // 澶勭悊鏁版嵁
+    this.MappingOperationBOMData( businessTypes, isKeyProduct, createPurchaseSupplyMaterial );
+    
+    // 搴撳瓨鎴愭湰
+    this.Broker_OTD_InventoryCost().Execute();
+    this.MappingInventoryValueAndCostData();
+    
+    // 搴撳瓨鏁版嵁
+    this.Broker_OTD_ActualPISPIP().Execute();
+    this.MappingActualPISPIPData( businessTypes, isKeyProduct )
+    
+    // Update the LastImportFromDatabase time
+    this.LastImportTime( DateTime::ActualTime() );
+    // sync to mp
+    if( not isnull( macroPlan ) ) {
+      macroPlan.SynchronizeFromMPSync( this, false, 
+                                       true, true, true, true, true,
+                                       true, true, true, true, true,
+                                       true, true, true, true, true,
+                                       true, true, true, true, true,
+                                       true, true, true, true );  
+    }
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/Method_MappingActualPISPIPData.qbl b/_Main/BL/Type_MPSync/Method_MappingActualPISPIPData.qbl
new file mode 100644
index 0000000..afc3888
--- /dev/null
+++ b/_Main/BL/Type_MPSync/Method_MappingActualPISPIPData.qbl
@@ -0,0 +1,30 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingActualPISPIPData (
+  Strings businessTypes,
+  Boolean nuclear
+)
+{
+  TextBody:
+  [*
+    this.IOActualProductInStockingPointInPeriod( relflush );
+    // 鍏堟寜鍏抽敭鐗╂枡锛屽啀鎸塨usinessType绛涢�変骇鍝�
+    productList := selectset( this, MappingProduct, item, item.KeyProduct() = nuclear );
+    if( not isnull( businessTypes ) and businessTypes.Size() > 0 ) {
+      productList := selectset( productList, Elements, item, businessTypes.Find( item.BusinessType() ) >= 0 );
+    }
+    productIdList := selectvalues( productList, Elements, item, item.ID() );
+    // 鏍规嵁浜у搧绛涢�夊簱瀛樻暟鎹�
+    traverse( this, MappingActualPISPIP, item, productIdList.Find( item.ProductID() ) >= 0 ) {
+      this.IOActualProductInStockingPointInPeriod( relnew, 
+                                                   ActualInventoryLevelEnd := item.ActualInventoryLevelEnd(), 
+                                                   // todo 纭浣跨敤褰撳墠鏃ユ湡杩樻槸鏁版嵁搴撴棩鏈�
+                                                   Date := item.Date(), 
+                                                   Description := item.Description(), 
+                                                   ManufacturedDate := item.ManufacturedDate(), 
+                                                   ProductID := item.ProductID(), 
+                                                   StockingPointID := item.StockingPointID() );
+                                                   
+    }
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/Method_MappingBaseConversionFactorData.qbl b/_Main/BL/Type_MPSync/Method_MappingBaseConversionFactorData.qbl
new file mode 100644
index 0000000..78cf5e9
--- /dev/null
+++ b/_Main/BL/Type_MPSync/Method_MappingBaseConversionFactorData.qbl
@@ -0,0 +1,19 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingBaseConversionFactorData
+{
+  Description: 'ETL鏁版嵁杞ā鍨嬫暟鎹�'
+  TextBody:
+  [*
+    this.IOBaseConversionFactor( relflush );
+    traverse( this, MappingBaseConversionFactor, item ) {
+    //  IOBaseConversionFactor::DeleteIfExist( this, item.SourceUnitOfMeasureName(), item.TargetUnitOfMeasureName(), item.ProductId() );
+      this.IOBaseConversionFactor( relnew, 
+                                   SourceUnitOfMeasureName := item.SourceUnitOfMeasureName(),
+                                   TargetUnitOfMeasureName := item.TargetUnitOfMeasureName(),
+                                   ProductID := item.ProductId(),
+                                   UserFactor := item.Factor(), 
+                                   IsEnabled := item.IsEnabled() );
+    }
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/Method_MappingCurencyRatesData.qbl b/_Main/BL/Type_MPSync/Method_MappingCurencyRatesData.qbl
new file mode 100644
index 0000000..b941727
--- /dev/null
+++ b/_Main/BL/Type_MPSync/Method_MappingCurencyRatesData.qbl
@@ -0,0 +1,28 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingCurencyRatesData (
+  JSON data
+)
+{
+  TextBody:
+  [*
+    data_length := data.Size();
+    for( i := 0; i < data_length; i++ )
+    {
+      datarow := data.Get( i );
+      currencyId := datarow.Get( "currencyid" ).GetString();
+      rate := [Real]datarow.Get( "rate" ).GetString();
+      startString := datarow.Get( "start" ).GetString();
+      years := [Number]startString.SubString( 0, 4 );
+      month := [Number]startString.SubString( 5, 2 );
+      day := [Number]startString.SubString( 8, 2 );
+      start := Date::Construct( years, month, day );
+      // 鍒犻櫎宸叉湁鐨�
+    //  IOCurrencyRate_MP::DeleteIfExist( this, currencyId, start );
+      this.IOCurrencyRate_MP( relnew, 
+                              CurrencyID := currencyId,
+                              Rate := rate,
+                              Start := start );
+    }
+  *]
+}
diff --git "a/_Main/BL/Type_MPSync/Method_MappingCurrencyData\043670.qbl" "b/_Main/BL/Type_MPSync/Method_MappingCurrencyData\043670.qbl"
new file mode 100644
index 0000000..b5acd8e
--- /dev/null
+++ "b/_Main/BL/Type_MPSync/Method_MappingCurrencyData\043670.qbl"
@@ -0,0 +1,23 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingCurrencyData (
+  JSON data
+)
+{
+  TextBody:
+  [*
+    data_length := data.Size();
+    for( i := 0; i < data_length; i++ )
+    {
+      datarow := data.Get( i );
+      id := datarow.Get( "id" ).GetString();
+      isBase := [Boolean]datarow.Get( "isbase" ).GetString();
+      name := datarow.Get( "name" ).GetString();
+      symbol := " ";
+      // 鍒犻櫎宸叉湁鐨�
+    //  IOCurrency_MP::DeleteIfExist( this, id );
+      this.IOCurrency_MP( relnew, 
+                          ID := id, IsBase := isBase, Name := name, Symbol := symbol );
+    }
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/Method_MappingCurrencyData.qbl b/_Main/BL/Type_MPSync/Method_MappingCurrencyData.qbl
new file mode 100644
index 0000000..8dae5ee
--- /dev/null
+++ b/_Main/BL/Type_MPSync/Method_MappingCurrencyData.qbl
@@ -0,0 +1,17 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingCurrencyData
+{
+  TextBody:
+  [*
+    this.IOCurrency_MP( relflush );
+    // 璐у竵淇℃伅
+    bodyNumber := "1";
+    postRequestBody := MPSync::ApiBuildPostRequestBody( bodyNumber );
+    address := "api-uat-sgc.tianma.cn";
+    url := "/otdService/https/GetCurrenciesInfo";
+    port := 443;
+    data := MPSync::ApiResponesCheck( address, port, url, postRequestBody );
+    this.MappingCurrencyData( data );
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/Method_MappingCurrencyRateData.qbl b/_Main/BL/Type_MPSync/Method_MappingCurrencyRateData.qbl
new file mode 100644
index 0000000..4335dd8
--- /dev/null
+++ b/_Main/BL/Type_MPSync/Method_MappingCurrencyRateData.qbl
@@ -0,0 +1,17 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingCurrencyRateData
+{
+  TextBody:
+  [*
+    this.IOCurrencyRate_MP( relflush );
+    // 璐у竵姹囩巼淇℃伅
+    bodynumber := "5";
+    postrequestbody := MPSync::ApiBuildPostRequestBody( bodynumber );
+    address := "api-uat-sgc.tianma.cn";
+    url := "/otdService/https/GetCurrencyRatesInfo";
+    port := 443;
+    data := MPSync::ApiResponesCheck( address, port, url, postrequestbody );
+    this.MappingCurencyRatesData( data );
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/Method_MappingCustomerOrderData.qbl b/_Main/BL/Type_MPSync/Method_MappingCustomerOrderData.qbl
new file mode 100644
index 0000000..c15e946
--- /dev/null
+++ b/_Main/BL/Type_MPSync/Method_MappingCustomerOrderData.qbl
@@ -0,0 +1,44 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingCustomerOrderData (
+  Strings businessTypes
+)
+{
+  Description: 'ETL璁㈠崟棰勬祴'
+  TextBody:
+  [*
+    toDels := selectset( this, IOSalesDemandBase, item, item.istype( IOCustomerOrder ) );
+    traverse( toDels, Elements, toDel ) {
+      toDel.Delete();  
+    }
+    // 寰呭鐞嗘暟鎹�
+    toDealList := selectset( this, MappingCustomerOrder, item, true );
+    if( not isnull( businessTypes ) and businessTypes.Size() > 0 ) {
+        toDealList := selectset( toDealList, Elements, item, businessTypes.Find( item.BusinessType() ) >= 0 );
+    }
+    // todo 娌acroPlan鎬庝箞鎼�
+    //queryStartDate := guard( DateTime::Now() - Duration::Days( 30 ), DateTime::MinDateTime() ).Date();
+    //queryEndDate := guard( max( this, Period_MP, item, true, item.EndDate() ), Date::MaxDate() );
+    //listToDeal := selectset( listToDeal, Elements, item, item.StartDate() >= queryStartDate and item.EndDate() <= queryEndDate );
+    // 澶勭悊
+    traverse( toDealList, Elements, item ) {
+      this.IOSalesDemandBase( relnew, 
+                              IOCustomerOrder, 
+                              ID := item.ID(), 
+                              CurrencyID := item.CurrencyID(), 
+                              PriorityName := item.PriorityName(),
+                              ProductID := item.ProductID(),
+                              SalesSegmentName := item.SalesSegmentName(), 
+                              StockingPointID := item.StockPointID(), 
+                              UnitOfMeasureName := item.UnitOfMeasureName(),
+                              CustomerID := item.CustomerID(),
+                              CustomerName := item.Customer(),
+                              OrderID := item.OrderID(), 
+                              OrderLineID := item.OrderLineID(),
+                              Price := item.Price(), 
+                              Quantity := item.Quantity(), 
+                              StartDate := item.OrderDate() );
+                              
+    }
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/Method_MappingExternalSupplyData.qbl b/_Main/BL/Type_MPSync/Method_MappingExternalSupplyData.qbl
new file mode 100644
index 0000000..f077a13
--- /dev/null
+++ b/_Main/BL/Type_MPSync/Method_MappingExternalSupplyData.qbl
@@ -0,0 +1,34 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingExternalSupplyData (
+  Strings businessTypes,
+  Boolean nuclear
+)
+{
+  TextBody:
+  [*
+    //// renhao Aug-14-2023 (created)
+    //
+    //traverse( this,MappingExternalSupply,externalSupply){
+    //  product := select( this,MappingProduct,product,product.ID() = externalSupply.ProductID() and product.KeyProduct() = nuclear,true);
+    //  
+    //  if( not isnull( product)){
+    //    productMP :=  select( this,Product_MP,productMP,productMP.ID() = externalSupply.ProductID() ,true);
+    //    stockingpoint := select( this,StockingPoint_MP,st,st.ID() = externalSupply.StockingPointID(),true);
+    //    if( not isnull(businessTypes)){
+    //    
+    //      for( i :=0 ;i < businessTypes.Size();i++ ){
+    //        businessType := businessTypes.Element( i);
+    //        if( product.BusinessType() = businessType and not product.IsCommon()){
+    //          InventorySupply::Create(externalSupply.ID(),productMP,stockingpoint,externalSupply.Date(),externalSupply.ManufacturedDate(),externalSupply.UserQuantity(),"鍦ㄩ�斿湪鍒�",true);
+    //        }
+    //      }
+    //      
+    //    }else{
+    //      InventorySupply::Create(externalSupply.ID(),productMP,stockingpoint,externalSupply.Date(),externalSupply.ManufacturedDate(),externalSupply.UserQuantity(),"鍦ㄩ�斿湪鍒�",true);
+    //    }
+    //    
+    //  }
+    //}
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/Method_MappingForecastData.qbl b/_Main/BL/Type_MPSync/Method_MappingForecastData.qbl
new file mode 100644
index 0000000..bfc14c3
--- /dev/null
+++ b/_Main/BL/Type_MPSync/Method_MappingForecastData.qbl
@@ -0,0 +1,40 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingForecastData (
+  Strings businessTypes
+)
+{
+  Description: 'ETL璁㈠崟棰勬祴'
+  TextBody:
+  [*
+    toDels := selectset( this, IOSalesDemandBase, item, item.istype( IOForecast ) );
+    traverse( toDels, Elements, toDel ) {
+      toDel.Delete();  
+    }
+    // 寰呭鐞嗘暟鎹�
+    listToDeal := selectset( this, MappingForecast, item, true );
+    if( not isnull( businessTypes ) and businessTypes.Size() > 0 ) {
+        listToDeal := selectset( listToDeal, Elements, item, businessTypes.Find( item.BusinessType() ) >= 0 );
+    }
+    // todo 娌acroPlan鎬庝箞鎼�
+    //queryStartDate := guard( DateTime::Now() - Duration::Days( 30 ), DateTime::MinDateTime() ).Date();
+    //queryEndDate := guard( max( this, Period_MP, item, true, item.EndDate() ), Date::MaxDate() );
+    //listToDeal := selectset( listToDeal, Elements, item, item.StartDate() >= queryStartDate and item.EndDate() <= queryEndDate );
+    // 澶勭悊
+    traverse( listToDeal, Elements, item ) {
+      this.IOSalesDemandBase( relnew, 
+                              IOForecast, 
+                              ID := item.ID(), 
+                              CurrencyID := item.CurrencyID(), 
+                              PriorityName := item.PriorityName(),
+                              SalesSegmentName := item.SalesSegmentName(),
+                              StockingPointID := item.StockingPointID(),
+                              UnitOfMeasureName := item.UnitOfMeasureName(),
+                              ProductID := item.ProductID(),
+                              StartDate := item.StartDate(), 
+                              EndDate := item.EndDate(), 
+                              Quantity := item.Quantity(),
+                              Price := item.Price());
+    }
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/Method_MappingInventoryValueAndCostData.qbl b/_Main/BL/Type_MPSync/Method_MappingInventoryValueAndCostData.qbl
new file mode 100644
index 0000000..3a8d758
--- /dev/null
+++ b/_Main/BL/Type_MPSync/Method_MappingInventoryValueAndCostData.qbl
@@ -0,0 +1,19 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingInventoryValueAndCostData
+{
+  TextBody:
+  [*
+    this.IOInventoryValueAndCost( relflush );
+    traverse( this, MappingInventoryValueAndCost, item ) {
+      this.IOInventoryValueAndCost( relnew, 
+                                    ID := item.ID(), 
+                                    AccountName := item.AccountName(), 
+                                    Cost := item.Cost(), 
+                                    CostDriver := item.CostDriver(), 
+                                    ProductID := item.ProductID(), 
+                                    Start := item.Start(), 
+                                    StockingPointID := item.StockingPointID() );     
+    }
+  *]
+}
diff --git "a/_Main/BL/Type_MPSync/Method_MappingLaneData\043474.qbl" "b/_Main/BL/Type_MPSync/Method_MappingLaneData\043474.qbl"
new file mode 100644
index 0000000..5757549
--- /dev/null
+++ "b/_Main/BL/Type_MPSync/Method_MappingLaneData\043474.qbl"
@@ -0,0 +1,23 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingLaneData (
+  JSON data
+)
+{
+  TextBody:
+  [*
+    dataLength := data.Size();
+    for( i := 0; i < dataLength; i++ ) {
+      dataRow := data.Get( i );
+      id := dataRow.Get( "id" ).GetString();
+      unitId := dataRow.Get( "unitid" ).GetString();
+      name := dataRow.Get( "name" ).GetString();
+      userLeadTimeHours := [Number]dataRow.Get( "userleadtime" ).GetString();
+      this.IOLane( relnew, 
+                   ID := id, 
+                   Name := name, 
+                   UnitID := unitId,
+                   UserLeadTime := Duration::Hours( userLeadTimeHours ) );
+    }
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/Method_MappingLaneData.qbl b/_Main/BL/Type_MPSync/Method_MappingLaneData.qbl
new file mode 100644
index 0000000..8e84a76
--- /dev/null
+++ b/_Main/BL/Type_MPSync/Method_MappingLaneData.qbl
@@ -0,0 +1,16 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingLaneData
+{
+  TextBody:
+  [*
+    this.IOLane( relflush );
+    bodyNumber := "3";
+    postRequestBody := MPSync::ApiBuildPostRequestBody( bodyNumber );
+    address := "api-uat-sgc.tianma.cn";
+    url := "/otdService/https/GetLanesInfo";
+    port := 443;
+    data := MPSync::ApiResponesCheck( address, port, url, postRequestBody );
+    this.MappingLaneData( data );
+  *]
+}
diff --git "a/_Main/BL/Type_MPSync/Method_MappingLaneLegData\043257.qbl" "b/_Main/BL/Type_MPSync/Method_MappingLaneLegData\043257.qbl"
new file mode 100644
index 0000000..0b5adf8
--- /dev/null
+++ "b/_Main/BL/Type_MPSync/Method_MappingLaneLegData\043257.qbl"
@@ -0,0 +1,30 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingLaneLegData (
+  JSON data
+)
+{
+  TextBody:
+  [*
+    dataLength := data.Size();
+    for( i := 0; i < dataLength; i++ ) {
+      dataRow := data.Get( i );
+      laneId := dataRow.Get( "laneid" ).GetString();
+      originStockingPointId := dataRow.Get( "originstockingpointid" ).GetString();
+      destinationStockingPointId := dataRow.Get( "destinationstockingpointid" ).GetString();
+      name := dataRow.Get( "name" ).GetString();
+      userLeadTimeHours := [Number]dataRow.Get( "userleadtime" ).GetString();
+      this.IOLaneLeg( relnew, 
+                      LaneID := laneId, 
+                      OriginStockingPointID := originStockingPointId, 
+                      DestinationStockingPointID := destinationStockingPointId,
+                      Name := name, 
+                      HasUserLeadTime := true,
+                      UserLeadTime := Duration::Hours( userLeadTimeHours ), 
+                      Start := Date::MinDate(), 
+                      End := Date::MaxDate(), 
+                      PreferenceBonus := 0.0,
+                      CO2Emission := 0.0 );           
+    }
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/Method_MappingLaneLegData.qbl b/_Main/BL/Type_MPSync/Method_MappingLaneLegData.qbl
new file mode 100644
index 0000000..edd9206
--- /dev/null
+++ b/_Main/BL/Type_MPSync/Method_MappingLaneLegData.qbl
@@ -0,0 +1,16 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingLaneLegData
+{
+  TextBody:
+  [*
+    this.IOLaneLeg( relflush );
+    bodynumber := "4";
+    postRequestBody := MPSync::ApiBuildPostRequestBody( bodynumber );
+    address := "api-uat-sgc.tianma.cn";
+    url := "/otdService/https/GetLaneLegsInfo";
+    port := 443;
+    data := MPSync::ApiResponesCheck( address, port, url, postRequestBody );
+    this.MappingLaneLegData( data );
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/Method_MappingOperationBOMData.qbl b/_Main/BL/Type_MPSync/Method_MappingOperationBOMData.qbl
new file mode 100644
index 0000000..1ba679a
--- /dev/null
+++ b/_Main/BL/Type_MPSync/Method_MappingOperationBOMData.qbl
@@ -0,0 +1,181 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingOperationBOMData (
+  Strings businessTypes,
+  Boolean isKeyProduct,
+  Boolean createPurchaseSupplyMaterial
+)
+{
+  TextBody:
+  [*
+    // keyProduct
+    keyProductIds := selectuniquevalues( this, MappingProduct, prod, prod.KeyProduct() = true, prod.ID() );
+    // 鑾峰彇鏈夊簭鐨勫緟澶勭悊璁板綍
+    toDealOps := construct( MappingOperations );
+    toDealBoms := construct( MappingBOMs );
+    if( not isnull( businessTypes ) and businessTypes.Size() > 0 ) {
+        toDealOps := selectsortedset( this, MappingOperation, item, 
+                                      businessTypes.Find( item.BusinessType() ) >= 0 
+                                      and ( not isKeyProduct or keyProductIds.Find( item.ProductID() ) >= 0 ), 
+                                      item.SequenceNumber() );
+        toDealBoms := selectset( this, MappingBOM, item, 
+                                 businessTypes.Find( item.BusinessType() ) >= 0 
+                                 and ( not isKeyProduct or keyProductIds.Find( item.ComponentCode() ) >= 0 ) );
+    } else {
+        toDealOps := selectsortedset( this, MappingOperation, item, 
+                                      not isKeyProduct or keyProductIds.Find( item.ProductID() ) >= 0 , 
+                                      item.SequenceNumber() );
+        toDealBoms := selectset( this, MappingBOM, item, 
+                                 businessTypes.Find( item.BusinessType() ) >= 0
+                                 and ( not isKeyProduct or keyProductIds.Find( item.ComponentCode() ) >= 0 ) );
+    }
+    // 瀵规瘡涓猺outing璁$畻inputGroupId
+    inputGroupId := 1
+    // 瀵规瘡涓猂outing杩涜鎶曞叆浜у嚭澶勭悊
+    routingKeys := selectuniquevalues( toDealOps, Elements, item, item.OrganCode() + "_" + item.ProductID() );
+    traverse( routingKeys, Elements, routingKey ) {
+      // ==== 浜у嚭 ====
+      // 鎵炬渶澶eq
+      maxSeq := max( toDealOps, Elements, item, item.OrganCode() + "_" + item.ProductID() = routingKey, item.SequenceNumber() );
+      maxSeqElements := selectset( toDealOps, Elements, item, 
+                                   item.OrganCode() + "_" + item.ProductID() = routingKey and item.SequenceNumber() = maxSeq );
+      traverse( maxSeqElements, Elements, maxSeqELement ) {
+        operationId := maxSeqELement.OrganCode() + "_" + maxSeqELement.ProductID() + "_" + maxSeqELement.ProcessSection();
+        if( maxSeqELement.Line() <> "" ) {
+          operationId := operationId + "_" + maxSeqELement.Line();
+        }
+        this.IOOperationBOM( relnew, 
+                             OperationID := operationId, 
+                             ProductID := maxSeqELement.ProductID(), 
+                             StockingPointID := maxSeqELement.OrganCode() + "_" + this.GetProductTypeByProductId( maxSeqELement.ProductID() ) + "_Stock", 
+                             Quantity := 1, 
+                             IsInput := false );
+      }
+      // ==== 鎶曞叆 ====
+      // 瀵筄peration涓殑姣忎釜ProcessSection锛� 鎵緎eq鏈�灏忕殑list锛屾瘡鏉om瀵硅list鐢熸垚operationBOM
+      processSectionList := selectuniquevalues( toDealOps, Elements, toDeal, 
+                                                toDeal.OrganCode() + "_" + toDeal.ProductID() = routingKey,
+                                                toDeal.ProcessSection() );
+      traverse( processSectionList, Elements, processSection ) {
+        minSeq := min( toDealOps, Elements, item, 
+                       item.OrganCode() + "_" + item.ProductID() = routingKey 
+                       and item.ProcessSection() = processSection,
+                       item.SequenceNumber() );
+        operationRecordsWithMinSeq := selectset( toDealOps, Elements, minSeqWithProcessSectionElement, 
+                                                 minSeqWithProcessSectionElement.OrganCode() + "_" + minSeqWithProcessSectionElement.ProductID() = routingKey 
+                                                 and minSeqWithProcessSectionElement.ProcessSection() = processSection
+                                                 and minSeqWithProcessSectionElement.SequenceNumber() = minSeq );
+        bomRecords := selectset( toDealBoms, Elements, bom, 
+                                 bom.OrganCode() + "_" + bom.ProductCode() = routingKey 
+                                 and bom.ProcessSection() = processSection );
+        // 鎸夋槸鍚︽湁鏇挎崲鏂欏垎缁�
+        bomWithoutAlters := selectset( bomRecords, Elements, bomRecord, bomRecord.AlternativeMaterialCode() = "" );
+        bomWithAlters := selectset( bomRecords, Elements, bomRecord, bomRecord.AlternativeMaterialCode() <> "" );
+        // 澶勭悊涓嶅甫鏇挎崲鏂欑殑input
+        traverse( operationRecordsWithMinSeq, Elements, op ) {
+          traverse( bomWithoutAlters, Elements, bom ) {
+            operationId := op.OrganCode() + "_" + op.ProductID() + "_" + op.ProcessSection();
+            if( op.Line() <> "" ) {
+              operationId := operationId + "_" + op.Line();
+            }
+            this.IOOperationBOM( relnew, 
+                                 OperationID := operationId, 
+                                 ProductID := op.ProductID(),
+                                 StockingPointID := op.OrganCode() + "_" + bom.ComponentType() + "_Stock", 
+                                 IsInput := true, 
+                                 Quantity := bom.UnitUsageOfComponents() / bom.ComponentOutputRate() );           
+          }
+        }
+        // 澶勭悊甯︽浛鎹㈡枡鐨勶紝鎸塴ine鍜屼富鏂欏垎缁�
+        lineList := selectuniquevalues( operationRecordsWithMinSeq, Elements, item, item.Line() );
+        mainProdList := selectuniquevalues( bomWithAlters, Elements, item, item.ComponentCode() );
+        traverse( lineList, Elements, line ) {
+          opWithLine := select( operationRecordsWithMinSeq, Elements, item, item.Line() = line );
+          opId := opWithLine.OrganCode() + "_" + opWithLine.ProductID() + "_" + opWithLine.ProcessSection();
+          if( opWithLine.Line() <> "" ) {
+            opId := opId + "_" + opWithLine.Line();
+          }
+          traverse( mainProdList, Elements, mainProd ) {
+            // 姣忕涓绘枡涓�涓猤roup
+            inputGroupId := inputGroupId + 1;
+            bomWithMainProdList := selectset( bomWithAlters, Elements, item, item.ComponentCode() = mainProd );
+            bomRandom := bomWithMainProdList.First();
+            // 鎬绘暟閲�
+            maxQuantityInGroup := bomRandom.UnitUsageOfComponents() / bomRandom.ComponentOutputRate();
+            // 鏇夸唬鏂欐�绘瘮渚�
+            alterRateTotal := sum( bomWithMainProdList, Elements, item, item.AlternativeRate() );
+            // 鍒涘缓inputGroup
+            this.IOOperationInputGroup( relnew, InputGroupID := inputGroupId, OperationID := opId, InputGroupQuantity := maxQuantityInGroup );
+            // 鍒涘缓涓绘枡鐨刬nput bom
+            this.IOOperationBOM( relnew, 
+                                 OperationID := opId, 
+                                 InputGroupID := inputGroupId,
+                                 ProductID := bomRandom.ComponentCode(),
+                                 StockingPointID := bomRandom.OrganCode() + "_" + bomRandom.ComponentType() + "_Stock", 
+                                 IsInput := true, 
+                                 Quantity := maxQuantityInGroup * ( 1 - alterRateTotal ), 
+                                 MinQuantityInGroup := 0.0, 
+                                 MaxQuantityInGroup := maxQuantityInGroup );  
+            // 鏇夸唬鏂檌nput bom
+            traverse( bomWithMainProdList, Elements, bom ) {
+              this.IOOperationBOM( relnew, 
+                         OperationID := opId, 
+                         InputGroupID := inputGroupId,
+                         ProductID := bom.AlternativeMaterialCode(),
+                         StockingPointID := bom.OrganCode() + "_" + bom.ComponentType() + "_Stock", 
+                         IsInput := true, 
+                         Quantity := maxQuantityInGroup * bom.AlternativeRate(), 
+                         MinQuantityInGroup := 0.0, 
+                         MaxQuantityInGroup := maxQuantityInGroup );  
+            }
+          }
+        }
+      }
+      // 閽堝姣忎釜routing 閲嶇疆 inputGroupId
+      inputGroupId := 1;
+    }
+    // 瀵规瘡涓狾rgCode_ComponentCode缁勫悎锛屽垱寤洪噰璐璻outing
+    if( createPurchaseSupplyMaterial ) {
+      toCreateKeys := selectuniquevalues( toDealBoms, Elements, bom,
+                                          bom.ComponentType() = "P", 
+                                          bom.OrganCode() + "_" + bom.ComponentCode() );
+      traverse( toCreateKeys, Elements, toCreateKey ) {
+        bomRandom := selectset( toDealBoms, Elements, bom, bom.ComponentType() = "P" and bom.OrganCode() + "_" + bom.ComponentCode() = toCreateKey ).First();
+        routingId := bomRandom.OrganCode() + "_" + bomRandom.ComponentCode();
+        routingName := routingId;
+        routingStepName := "閲囪喘";
+        routingStepSeq := 1;
+        operationId := bomRandom.OrganCode() + "_PR_" + bomRandom.ComponentCode();
+        operationName := operationId;
+        unitId := "渚涘簲鍟�";
+        // ==== 鍒涘缓 ====
+        // 鍒涘缓routing
+        this.IORouting( relnew, 
+                        ID := routingId, Name := routingName, IsEnabled := true, Start := Date::MinDate(), End := Date::MaxDate() );
+        // 鍒涘缓routingStep
+        IORoutingStep::CreateIfNotExist( this, 
+                                     routingId,
+                                     routingStepName,
+                                     routingStepSeq );
+        // 鍒涘缓op
+        ioOp := IOOperation::CreateIfNotExist( this, operationId );
+        ioOp.UnitID( unitId );
+        ioOp.RoutingID( routingId );
+        ioOp.RoutingStepName( routingStepName );
+        ioOp.Name( operationName );
+        ioOp.UserLeadTime( Duration::Zero() );
+        ioOp.Throughput( 1.0 );
+        ioOp.HasUserMaximumQuantity( false );
+        ioOp.UserMinimumQuantity( Real::MinReal() );
+        ioOp.UserMaximumQuantity( Real::MaxReal() );
+        // 鍒涘缓opBOM
+        this.IOOperationBOM( relnew, 
+                   OperationID := operationId, 
+                   ProductID := bomRandom.ComponentCode(),
+                   StockingPointID := bomRandom.OrganCode() + "_" + bomRandom.ComponentType() + "_Stock", 
+                   IsInput := true, 
+                   Quantity := 1 );  
+      }
+    }
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/Method_MappingOperationCostData.qbl b/_Main/BL/Type_MPSync/Method_MappingOperationCostData.qbl
new file mode 100644
index 0000000..30509c6
--- /dev/null
+++ b/_Main/BL/Type_MPSync/Method_MappingOperationCostData.qbl
@@ -0,0 +1,55 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingOperationCostData (
+  Strings businesstypes
+)
+{
+  Description: 'Get operation cost data from operation mapping'
+  TextBody:
+  [*
+    //// Administrator Aug-21-2023 (created)
+    //// list to deal
+    //listtodeal := construct( structured[MappingOperation] );
+    //
+    //if( isnull( businesstypes ) or businesstypes.Size() = 0 ) {
+    //    listtodeal := selectset( this, MappingOperation, item, true );
+    //} else {
+    //    listtodeal := selectset( this, MappingOperation, item, businesstypes.Find( item.BusinessType() ) <> -1 );
+    //}
+    //
+    //// Get the list to deal with max sequence number
+    //listtodealwithmaxsn := construct( structured[MappingOperation] );
+    //traverse( listtodeal, Elements, item ){
+    //  maxsn := maxselect( this, 
+    //                      MappingOperation, 
+    //                      moperation, 
+    //                      moperation.OrganCode() = item.OrganCode(), 
+    //                      moperation.ProductID() = item.ProductID(), 
+    //                      moperation.SequenceNumber() ).SequenceNumber()
+    //  if( item.SequenceNumber() = maxsn ){
+    //    listtodealwithmaxsn.Add( item );
+    //    }
+    //  }
+    //
+    //// Get the operation cost data
+    //traverse( listtodealwithmaxsn, Elements, item ){
+    //  id := item.OrganCode() + "_" + item.ProductID() + "_" + item.ProcessSection() + "_" + item.Line();
+    //  operation := Operation::FindOperationTypeIndex( id );
+    //  account := Account_MP::FindByName( this, "Operation cost" );
+    //  isfromdb := false;
+    //  existoperationcost := OperationCost::FindOperationCostTypeIndex( id );
+    //  if( isnull( existoperationcost ) ){
+    //    connecteditem := select( this, 
+    //                             MappingOperationCost, 
+    //                             moperationcost, 
+    //                             moperationcost.OrgCode() = item.OrganCode(), 
+    //                             moperationcost.ProductID() = item.ProductID() );
+    //    cost := connecteditem.Cost();
+    //    lengthoftime := connecteditem.LengthOfTime();
+    //    start := connecteditem.Start();
+    //    timeunit := connecteditem.TimeUnit();
+    //    OperationCost::Create( id, operation, account, "Volume", start, timeunit, lengthoftime, cost, isfromdb );
+    //    }
+    //  }
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/Method_MappingOperationData.qbl b/_Main/BL/Type_MPSync/Method_MappingOperationData.qbl
new file mode 100644
index 0000000..b03e439
--- /dev/null
+++ b/_Main/BL/Type_MPSync/Method_MappingOperationData.qbl
@@ -0,0 +1,102 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingOperationData (
+  Strings businessTypes
+)
+{
+  TextBody:
+  [*
+    // 鑾峰彇鏈夊簭鐨勫緟澶勭悊璁板綍
+    toDealList := construct( MappingOperations );
+    if( not isnull( businessTypes ) and businessTypes.Size() > 0 ) {
+        toDealList := selectsortedset( this, MappingOperation, item, 
+                                       businessTypes.Find( item.BusinessType() ) >= 0, 
+                                       item.SequenceNumber() );
+    } else {
+        toDealList := selectsortedset( this, MappingOperation, item, 
+                                       true, 
+                                       item.SequenceNumber() );
+    }
+    // 鍒犻櫎鍘熸湁routing
+    this.IORouting( relflush );
+    // 鏂皉outing
+    routingIdList := selectuniquevalues( toDealList, Elements, item, item.OrganCode() + "_" + item.ProductID() );
+    traverse( routingIdList, Elements, routingId ) {
+      this.IORouting( relnew, 
+                      ID := routingId, Name := routingId, IsEnabled := true );
+    }
+    // 鍒犻櫎鍘熸湁routingStep
+    this.IORoutingStep( relflush );
+    // 鏂皉outingStep
+    traverse( toDealList, Elements, op ) {
+      routingId := op.OrganCode() + "_" + op.ProductID();
+      routingStepName := op.ProcessSection() + "_" + [String]op.SequenceNumber();
+      IORoutingStep::CreateIfNotExist( this, 
+                                       routingId,
+                                       routingStepName,
+                                       op.SequenceNumber() );
+    }
+    // 鏂皁peration
+    traverse( toDealList, Elements, op ) {
+      // 姹囨�绘暟鎹�
+      routingId := op.OrganCode() + "_" + op.ProductID();
+      routingStepName := op.ProcessSection() + "_" + [String]op.SequenceNumber();
+      opId := op.OrganCode() + "_" + op.ProductID() + "_" + op.ProcessSection();
+      unitId := op.OrganCode() + "_" + op.ProcessSection();
+      if( op.Line() <> "" ) {
+        opId := opId + "_" + op.Line();
+        unitId := unitId + "_" + op.Line();
+      }
+      opName := opId;
+      // 鏂板缓
+      ioOp := IOOperation::CreateIfNotExist( this, opId );
+      ioOp.UnitID( unitId );
+      ioOp.RoutingID( routingId );
+      ioOp.RoutingStepName( routingStepName );
+      ioOp.Name( opName );
+      ioOp.UserLeadTime( Duration::Hours( op.UserLeadTime() ) );
+      ioOp.Throughput( op.ActualCapacity() );
+      ioOp.UserMinimumQuantity( op.MinimumQuantity() );
+      ioOp.UserMaximumQuantity( op.MaximumQuantity() );
+      ioOp.HasUserMaximumQuantity( op.MaximumQuantity() <> 0.0 );
+    }
+    // 鎸� OrganCode + ProductID 鍒嗙粍 + 鎺掑簭
+    keyList := selectuniquevalues( toDealList, Elements, op, 
+                                   op.OrganCode() + "_" + op.ProductID() );
+    keyList := selectsortedset( keyList, Elements, str, str );
+    traverse( keyList, Elements, key ) {
+      previousList := construct( MappingOperations );
+      // 鎸� SequenceNumber 鍒嗙粍 + 鎺掑簭
+      subKeyList := selectuniquevalues( toDealList, Elements, op, 
+                                        key = op.OrganCode() + "_" + op.ProductID(),
+                                        op.SequenceNumber() );
+      subKeyList := selectsortedset( subKeyList, Elements, seq, seq );
+      // 閬嶅巻姣忎釜Seq锛屼笌鍓嶄竴涓猯ist杩涜杩炴帴锛屽悓鏃跺垱寤篻roup
+      traverse( subKeyList, Elements, seq ) {
+        elementList := selectset( this, MappingOperation, op, 
+                                  op.OrganCode() + "_" + op.ProductID() = key and op.SequenceNumber() = seq );
+        if( not isnull( previousList ) and previousList.Size() > 0 ) {
+          // 瀵规瘡涓洰鏍囧垱寤篿nputGroup
+          if( previousList.Size() > 1 ) {
+            traverse( elementList, Elements, targetOp ) {
+              targetOpId := targetOp.OrganCode() + "_" + targetOp.ProductID() + "_" + targetOp.ProcessSection();
+              this.IOOperationInputGroup( relnew, InputGroupID := 1, OperationID := targetOpId, InputGroupQuantity := 1 );
+            }
+          }
+          // 婧愪笌鐩爣涓や袱鍒涘缓operationLink
+          traverse( elementList, Elements, targetOp ) {
+            traverse( previousList, Elements, sourceOp ) {
+              sourceOpId := sourceOp.OrganCode() + "_" + sourceOp.ProductID() + "_" + sourceOp.ProcessSection();
+              targetOpId := targetOp.OrganCode() + "_" + targetOp.ProductID() + "_" + targetOp.ProcessSection();
+              this.IOOperationLink( relnew, 
+                                    SourceOperationID := sourceOpId, DestOperationID := targetOpId, 
+                                    SourceGroupID := 1, DestGroupID := 1, SourceQuantity := 1, DestQuantity := 1 / previousList.Size(), 
+                                    DestHasUserQuantity := false, DestMinQuantity := 0, DestMaxQuantity := 1 );
+            }  
+          }
+        }
+        previousList := elementList;
+      }
+    }
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/Method_MappingProductData.qbl b/_Main/BL/Type_MPSync/Method_MappingProductData.qbl
new file mode 100644
index 0000000..4a5f907
--- /dev/null
+++ b/_Main/BL/Type_MPSync/Method_MappingProductData.qbl
@@ -0,0 +1,47 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingProductData (
+  Strings businesstypes,
+  Boolean iskeyproduct
+)
+{
+  Description: 'Method to get needed data from mapping product data'
+  TextBody:
+  [*
+    // 娓呴櫎鏃ф暟鎹�
+    this.IOProduct_MP( relflush );
+    // list to deal
+    listToDeal := construct( structured[MappingProduct] );
+    if( isnull( businesstypes ) or businesstypes.Size() = 0 ) {
+      if( iskeyproduct = true ){
+        listToDeal := selectset( this, MappingProduct, item, item.KeyProduct() = true );
+      } else {
+        listToDeal := selectset( this, MappingProduct, item, true );
+      }
+    } else {
+      if( iskeyproduct = true ){
+        listToDeal := selectset( this, MappingProduct, item, item.KeyProduct() = true, businesstypes.Find( item.BusinessType() ) <> -1 or businesstypes.Find( item.CommonBusiness() ) <> -1 );
+      } else {
+        listToDeal := selectset( this, MappingProduct, item, businesstypes.Find( item.BusinessType() ) <> -1 or businesstypes.Find( item.CommonBusiness() ) <> -1 );
+      }
+    }
+    // 鍒涘缓鏍逛骇鍝�
+    IOProduct_MP::CreateIfNotExist( this, "鍏ㄩ儴鐗╂枡浜у搧", "鍏ㄩ儴鐗╂枡浜у搧", "", "PCS" );
+    // 澶勭悊鏂颁俊鎭�
+    traverse( listToDeal, Elements, item ) {
+      // 鍒涘缓鐖朵骇鍝�
+      IOProduct_MP::CreateIfNotExist( this, item.ProductMajorType(), item.ProductMajorType(), "鍏ㄩ儴鐗╂枡", "PCS" );
+      IOProduct_MP::CreateIfNotExist( this, item.ProductSubclassType(), item.ProductSubclassType(), item.ProductMajorType(), "PCS" );
+      // 鍒涘缓浜у搧
+      this.IOProduct_MP( relnew, 
+                         ID := item.ID(), 
+                         Name := item.Name(), 
+                         ParentID := item.ProductSubclassType(), 
+                         UOMName := item.UnitOfMeasureName(),
+                         // todo ?
+                         HasShelfLife := true, 
+                         ShelfLife := item.ShelfLife(),
+                         Notes := item.Notes() );
+    }
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/Method_MappingProductInLaneData.qbl b/_Main/BL/Type_MPSync/Method_MappingProductInLaneData.qbl
new file mode 100644
index 0000000..4b1a242
--- /dev/null
+++ b/_Main/BL/Type_MPSync/Method_MappingProductInLaneData.qbl
@@ -0,0 +1,15 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingProductInLaneData
+{
+  Description: 'Get Product In Line data'
+  TextBody:
+  [*
+    this.IOProductInLane( relflush );
+    traverse( this, MappingProductInLane, item ){
+      this.IOProductInLane( relnew, 
+                            LaneID := item.LineID(),
+                            ProductID := item.ProductID() );
+    }
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/Method_MappingSalesLevelData.qbl b/_Main/BL/Type_MPSync/Method_MappingSalesLevelData.qbl
new file mode 100644
index 0000000..0baf2aa
--- /dev/null
+++ b/_Main/BL/Type_MPSync/Method_MappingSalesLevelData.qbl
@@ -0,0 +1,18 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingSalesLevelData
+{
+  TextBody:
+  [*
+    this.IOSalesLevel_MP( relflush );
+    this.IOSalesLevel_MP( relnew, 
+                          Level := 0,
+                          Name := "钀ラ攢涓績" );
+    this.IOSalesLevel_MP( relnew, 
+                          Level := 1,
+                          Name := "閿�鍞" );
+    this.IOSalesLevel_MP( relnew, 
+                          Level := 2,
+                          Name := "瀹㈡埛" );
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/Method_MappingSalesSegmentData.qbl b/_Main/BL/Type_MPSync/Method_MappingSalesSegmentData.qbl
new file mode 100644
index 0000000..d92ea1e
--- /dev/null
+++ b/_Main/BL/Type_MPSync/Method_MappingSalesSegmentData.qbl
@@ -0,0 +1,23 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingSalesSegmentData (
+  Strings businessTypes
+)
+{
+  Description: 'ETL閿�鍞儴闂�'
+  TextBody:
+  [*
+    this.IOSalesSegment_MP( relflush );
+    toDealList := selectset( this, MappingSalesSegment, item, true );
+    if( not isnull( businessTypes ) and businessTypes.Size() > 0 ) {
+        toDealList := selectset( toDealList, Elements, item, businessTypes.Find( item.BusinessType() ) >= 0 );
+    }
+    
+    traverse( toDealList, Elements, item ) {
+        this.IOSalesSegment_MP( relnew, 
+                                Name := item.Name(), 
+                                ParentName := item.ParentName(),
+                                DisplayIndex := item.DisplayIndex() );
+    }
+  *]
+}
diff --git "a/_Main/BL/Type_MPSync/Method_MappingStockingPointData\043321.qbl" "b/_Main/BL/Type_MPSync/Method_MappingStockingPointData\043321.qbl"
new file mode 100644
index 0000000..cfe65b5
--- /dev/null
+++ "b/_Main/BL/Type_MPSync/Method_MappingStockingPointData\043321.qbl"
@@ -0,0 +1,29 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingStockingPointData (
+  JSON data
+)
+{
+  TextBody:
+  [*
+    dataLength := data.Size();
+    for( i:=0; i < dataLength; i++ )
+    {
+      dataRow := data.Get( i );
+      id := dataRow.Get( "id" ).GetString();
+      unitId := dataRow.Get( "unitid" ).GetString();
+      name := dataRow.Get( "name" ).GetString();
+      this.IOStockingPoint_MP( relnew, 
+                               ID := id, 
+                               Name := name, 
+                               UnitID := unitId, 
+                               CurrencyID := "CNY", 
+                               UnitOfMeasureName := "PCS",
+                               IsPlannedInfinite := false,
+                               GroupName := " ",
+                               Notes := " ", 
+                               Start := Date::MinDate(), 
+                               End := Date::MaxDate() );
+    }
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/Method_MappingStockingPointData.qbl b/_Main/BL/Type_MPSync/Method_MappingStockingPointData.qbl
new file mode 100644
index 0000000..b09b6be
--- /dev/null
+++ b/_Main/BL/Type_MPSync/Method_MappingStockingPointData.qbl
@@ -0,0 +1,16 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingStockingPointData
+{
+  TextBody:
+  [*
+    this.IOStockingPoint_MP( relflush );
+    bodyNumber := "2";
+    postRequestBody := MPSync::ApiBuildPostRequestBody( bodyNumber );
+    address := "api-uat-sgc.tianma.cn";
+    port := 443;
+    url := "/otdService/https/GetStockingPointsInfo";
+    data := MPSync::ApiResponesCheck( address, port, url, postRequestBody );
+    this.MappingStockingPointData( data );
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/Method_MappingUnitData.qbl b/_Main/BL/Type_MPSync/Method_MappingUnitData.qbl
new file mode 100644
index 0000000..eaec58b
--- /dev/null
+++ b/_Main/BL/Type_MPSync/Method_MappingUnitData.qbl
@@ -0,0 +1,52 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingUnitData (
+  Strings businessTypes
+)
+{
+  Description: 'Get unit data from operation mapping'
+  TextBody:
+  [*
+    listToDeal := selectset( this, MappingOperation, item, true );
+    if( not isnull( businessTypes ) and businessTypes.Size() > 0 ) {
+      listToDeal := selectset( this, MappingOperation, item, businessTypes.Find( item.BusinessType() ) >= 0 );
+    }
+    // 甯搁噺
+    unitOfMeasureName := "PCS";
+    currencyId := "CNY";
+    startDate := Date::Date( 1900, 1, 1 );
+    endDate := Date::Date( 9999, 12, 31 );
+    capacityType := "Infinite";
+    // 閫愮骇鍒涘缓
+    IOUnit::CreateIfNotExistByTree( this, "澶╅┈闆嗗洟", "澶╅┈闆嗗洟", "", unitOfMeasureName, currencyId, startDate, endDate, capacityType );
+    IOUnit::CreateIfNotExistByTree( this, "鐢熶骇", "鐢熶骇", "澶╅┈闆嗗洟", unitOfMeasureName, currencyId, startDate, endDate, capacityType );
+    IOUnit::CreateIfNotExistByTree( this, "渚涘簲鍟�", "渚涘簲鍟�", "澶╅┈闆嗗洟", unitOfMeasureName, currencyId, startDate, endDate, capacityType );
+    IOUnit::CreateIfNotExistByTree( this, "鏁磋溅杩愯緭", "鏁磋溅杩愯緭", "澶╅┈闆嗗洟", unitOfMeasureName, currencyId, startDate, endDate, capacityType );
+    // 鏍规嵁operation鍒涘缓
+    traverse( listToDeal, Elements, op ) {
+      // 涓�绾� orgCode
+      levelOne := op.OrganCode();
+      IOUnit::CreateIfNotExistByTree( this, 
+                                      levelOne, op.OrganName(), "鐢熶骇", 
+                                      unitOfMeasureName, currencyId, startDate, endDate, capacityType );
+      // 浜岀骇 orgCode + plantName
+      levelTwo := op.OrganCode() + "_" + op.PlantName();
+      IOUnit::CreateIfNotExistByTree( this, 
+                                      levelTwo, levelTwo, levelOne, 
+                                      unitOfMeasureName, currencyId, startDate, endDate, capacityType );
+      // 涓夌骇 浜岀骇 + processSection
+      levelThree := levelTwo + "_" + op.ProcessSection();
+      IOUnit::CreateIfNotExistByTree( this, 
+                                      levelThree, levelThree, levelTwo, 
+                                      unitOfMeasureName, currencyId, startDate, endDate, capacityType );
+      // 鍥涚骇 涓夌骇 + line
+      if( op.Line() <> "" ) {
+        levelFour := levelThree + "_" + op.Line();
+        IOUnit::CreateIfNotExistByTree( this, 
+                                        levelFour, levelFour, levelThree, 
+                                        unitOfMeasureName, currencyId, startDate, endDate, capacityType );
+      }
+      
+    }
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/Method_MappingUnitOfMeasureData.qbl b/_Main/BL/Type_MPSync/Method_MappingUnitOfMeasureData.qbl
new file mode 100644
index 0000000..066fe15
--- /dev/null
+++ b/_Main/BL/Type_MPSync/Method_MappingUnitOfMeasureData.qbl
@@ -0,0 +1,14 @@
+Quintiq file version 2.0
+#parent: #root
+Method MappingUnitOfMeasureData
+{
+  Description: 'ETL鏁版嵁杞ā鍨嬫暟鎹�'
+  TextBody:
+  [*
+    this.IOUnitOfMeasure_MP( relflush );
+    traverse( this, MappingUnitOfMeasure, item ) {
+    //  IOUnitOfMeasure_MP::DeleteIfExist( this, item.Name() );
+      this.IOUnitOfMeasure_MP( relnew, IsDefault := item.IsDefault(), Name :=  item.Name() );
+    }
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/StaticMethod_ApiBuildPostRequestBody.qbl b/_Main/BL/Type_MPSync/StaticMethod_ApiBuildPostRequestBody.qbl
new file mode 100644
index 0000000..d7495b1
--- /dev/null
+++ b/_Main/BL/Type_MPSync/StaticMethod_ApiBuildPostRequestBody.qbl
@@ -0,0 +1,25 @@
+Quintiq file version 2.0
+#parent: #root
+StaticMethod ApiBuildPostRequestBody (
+  String bodynumber
+) as String
+{
+  TextBody:
+  [*
+    postrequestbody := JSON::Object()
+                        .Add( "serviceInterfaceCode", "ESBOTDH000" + bodynumber )
+                        .Add( "fromSystemCode", "OTDH000" + bodynumber )
+                        .Add( "toInterfaceCode", "QIDH000" + bodynumber )
+                        .Add( "ouZone", "OU_TMSH" )
+                        .Add( "uuid", "1617355496bb588e353e80147eea5f45" )
+                        .Add( "requestTime", DateTime::Now().Format( "Y-M2-D2 H:m:s" ) )
+                        .Add( "dataType", "JSON" )
+                        .Add( "data", JSON::Object()
+                                      .Add( "pageIndex", "1" ) ).Build();
+    
+    info( DateTime::Now().Format( "Y-M2-D2 H:m:s" ) );
+    postrequestbodystring := postrequestbody.AsString();
+    
+    return postrequestbodystring;
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/StaticMethod_ApiResponesCheck.qbl b/_Main/BL/Type_MPSync/StaticMethod_ApiResponesCheck.qbl
new file mode 100644
index 0000000..ac1f3c0
--- /dev/null
+++ b/_Main/BL/Type_MPSync/StaticMethod_ApiResponesCheck.qbl
@@ -0,0 +1,54 @@
+Quintiq file version 2.0
+#parent: #root
+StaticMethod ApiResponesCheck (
+  String address,
+  Number port,
+  String path,
+  String postrequestbody
+) as owning JSON
+{
+  TextBody:
+  [*
+    // for HTTPS requests:
+    i := HTTPInterface::Create( address, port );
+    //i := HTTPInterface::Create( address ,443);
+    info( address, port, path, postrequestbody );
+    
+    i.URL(path);
+    //i.SSL(false);
+    i.SSL(true);
+    i.SSLKeystore('MyKeystore'); // created in the Config Utility
+    
+    i.PostMethod(true); //it's a POST method
+    
+    i.Call(postrequestbody); // Call's argument is for POST method's content.
+    htmlresult := i.Result();
+    
+    htmlresponse := JSON::Parse( htmlresult );
+    
+    code := htmlresponse.Get( "resultCode" ).GetString();
+    message := htmlresponse.Get( "resultMsg" );
+    data := htmlresponse.Get( "responseData" );
+    datalist := data.Get( "dataList" );
+    
+    if( code = "1" )
+    {
+      info( "Data have been written into table" );
+      }
+    else
+    {
+      messagestring := " ";
+      if ( message.IsNull() )
+      {
+        messagestring := "No message returns!";
+        }
+      else
+      {
+        messagestring := message.GetString();
+        }
+      info( "Error! error code: " + code + ", error message: " + messagestring );
+      }
+    
+    return &datalist;
+  *]
+}
diff --git a/_Main/BL/Type_MPSync/_ROOT_Type_MPSync.qbl b/_Main/BL/Type_MPSync/_ROOT_Type_MPSync.qbl
new file mode 100644
index 0000000..2e63828
--- /dev/null
+++ b/_Main/BL/Type_MPSync/_ROOT_Type_MPSync.qbl
@@ -0,0 +1,6 @@
+Quintiq file version 2.0
+#root
+#parent: #DomainModel
+Type MPSync #extension
+{
+}
diff --git "a/_Main/BL/Type_MacroPlan/StaticMethod_DoSyncNew\043331.qbl" "b/_Main/BL/Type_MacroPlan/StaticMethod_DoSyncNew\043331.qbl"
new file mode 100644
index 0000000..dc03063
--- /dev/null
+++ "b/_Main/BL/Type_MacroPlan/StaticMethod_DoSyncNew\043331.qbl"
@@ -0,0 +1,21 @@
+Quintiq file version 2.0
+#parent: #root
+StaticMethod DoSyncNew (
+  MacroPlan macroPlan,
+  MPSync mpSync,
+  String businessTypeStr,
+  Boolean isKeyProduct,
+  Boolean createPurchaseSupplyMaterial
+)
+{
+  Description: '鍗曟鍚屾'
+  TextBody:
+  [*
+    // yypsybs Aug-17-2023 (created)
+    businessTypes := construct( Strings );
+    if( businessTypeStr.Length() > 0 ) {
+        businessTypes := businessTypeStr.Tokenize( ',' );
+    }
+    MacroPlan::DoSyncNew( macroPlan, mpSync, businessTypes, isKeyProduct, createPurchaseSupplyMaterial );
+  *]
+}
diff --git "a/_Main/BL/Type_MacroPlan/StaticMethod_DoSyncNew\043821.qbl" "b/_Main/BL/Type_MacroPlan/StaticMethod_DoSyncNew\043821.qbl"
new file mode 100644
index 0000000..c7824af
--- /dev/null
+++ "b/_Main/BL/Type_MacroPlan/StaticMethod_DoSyncNew\043821.qbl"
@@ -0,0 +1,17 @@
+Quintiq file version 2.0
+#parent: #root
+StaticMethod DoSyncNew (
+  MacroPlan macroPlan,
+  MPSync mpSync,
+  Boolean isKeyProduct,
+  Boolean createPurchaseSupplyMaterial
+)
+{
+  Description: '鍗曟鍚屾'
+  TextBody:
+  [*
+    // yypsybs Aug-17-2023 (created)
+    businessTypes := construct( Strings );
+    MacroPlan::DoSyncNew( macroPlan, mpSync, businessTypes, isKeyProduct, createPurchaseSupplyMaterial );
+  *]
+}
diff --git a/_Main/BL/Type_MacroPlan/StaticMethod_DoSyncNew.qbl b/_Main/BL/Type_MacroPlan/StaticMethod_DoSyncNew.qbl
new file mode 100644
index 0000000..a66613b
--- /dev/null
+++ b/_Main/BL/Type_MacroPlan/StaticMethod_DoSyncNew.qbl
@@ -0,0 +1,17 @@
+Quintiq file version 2.0
+#parent: #root
+StaticMethod DoSyncNew (
+  MacroPlan macroPlan,
+  MPSync mpSync,
+  Strings businessTypes,
+  Boolean isKeyProduct,
+  Boolean createPurchaseSupplyMaterial
+)
+{
+  Description: '鍗曟鍚屾'
+  TextBody:
+  [*
+    // yypsybs Aug-31-2023 (created)
+    mpSync.ImportDBDataCustom( macroPlan, businessTypes, isKeyProduct, createPurchaseSupplyMaterial );
+  *]
+}
diff --git a/_Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Response_MacroPlanner_mbMainMenu_MenuTestCurrencyData_OnClick.def b/_Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Response_MacroPlanner_mbMainMenu_MenuTestCurrencyData_OnClick.def
new file mode 100644
index 0000000..adde90d
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Response_MacroPlanner_mbMainMenu_MenuTestCurrencyData_OnClick.def
@@ -0,0 +1,13 @@
+Quintiq file version 2.0
+#parent: mbMainMenu/MenuTestCurrencyData
+Response OnClick () id:Response_MacroPlanner_mbMainMenu_MenuTestCurrencyData_OnClick
+{
+  #keys: '[414502.0.88134030]'
+  Body:
+  [*
+    // Click to start a dialog about lane data test
+    dlg := construct( CurrencyDataTestDialog );
+    dlg.OpenDialog( Application );
+  *]
+  DefinitionID: 'Responsedef_Menu_OnClick'
+}
diff --git a/_Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Response_MacroPlanner_mbMainMenu_MenuTestCurrency_OnClick.def b/_Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Response_MacroPlanner_mbMainMenu_MenuTestCurrency_OnClick.def
new file mode 100644
index 0000000..375e8df
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Response_MacroPlanner_mbMainMenu_MenuTestCurrency_OnClick.def
@@ -0,0 +1,13 @@
+Quintiq file version 2.0
+#parent: mbMainMenu/MenuTestCurrency
+Response OnClick () id:Response_MacroPlanner_mbMainMenu_MenuTestCurrency_OnClick
+{
+  #keys: '[414502.0.88134200]'
+  Body:
+  [*
+    // Click to start a dialog about lane data test
+    dlg := construct( CurrencyRateDataTestDialog );
+    dlg.OpenDialog( Application );
+  *]
+  DefinitionID: 'Responsedef_Menu_OnClick'
+}
diff --git a/_Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Response_MacroPlanner_mbMainMenu_MenuTestLanesData_OnClick.def b/_Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Response_MacroPlanner_mbMainMenu_MenuTestLanesData_OnClick.def
new file mode 100644
index 0000000..1178192
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Response_MacroPlanner_mbMainMenu_MenuTestLanesData_OnClick.def
@@ -0,0 +1,13 @@
+Quintiq file version 2.0
+#parent: mbMainMenu/MenuTestLanesData
+Response OnClick () id:Response_MacroPlanner_mbMainMenu_MenuTestLanesData_OnClick
+{
+  #keys: '[414502.0.18234397]'
+  Body:
+  [*
+    // Click to start a dialog about lane data test
+    dlg := construct( LanesDataTestDialog );
+    dlg.OpenDialog( Application );
+  *]
+  DefinitionID: 'Responsedef_Menu_OnClick'
+}
diff --git a/_Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Response_MacroPlanner_mbMainMenu_MenuTestLanesLegsData_OnClick.def b/_Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Response_MacroPlanner_mbMainMenu_MenuTestLanesLegsData_OnClick.def
new file mode 100644
index 0000000..1c7baf7
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Response_MacroPlanner_mbMainMenu_MenuTestLanesLegsData_OnClick.def
@@ -0,0 +1,13 @@
+Quintiq file version 2.0
+#parent: mbMainMenu/MenuTestLanesLegsData
+Response OnClick () id:Response_MacroPlanner_mbMainMenu_MenuTestLanesLegsData_OnClick
+{
+  #keys: '[412960.0.15704079]'
+  Body:
+  [*
+    // Click to start a dialog about lane data test
+    dlg := construct( LanesLegsDataTestDialog );
+    dlg.OpenDialog( Application );
+  *]
+  DefinitionID: 'Responsedef_Menu_OnClick'
+}
diff --git a/_Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Response_MacroPlanner_mbMainMenu_MenuTestStockpointData_OnClick.def b/_Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Response_MacroPlanner_mbMainMenu_MenuTestStockpointData_OnClick.def
new file mode 100644
index 0000000..6ff38a8
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Response_MacroPlanner_mbMainMenu_MenuTestStockpointData_OnClick.def
@@ -0,0 +1,13 @@
+Quintiq file version 2.0
+#parent: mbMainMenu/MenuTestStockpointData
+Response OnClick () id:Response_MacroPlanner_mbMainMenu_MenuTestStockpointData_OnClick
+{
+  #keys: '[414502.0.18234233]'
+  Body:
+  [*
+    // Click to start a new dialog about stockpoint data test
+    dlg := construct( StockpointDataTestDialog );
+    dlg.OpenDialog( Application );
+  *]
+  DefinitionID: 'Responsedef_Menu_OnClick'
+}
diff --git a/_Main/UI/MacroPlanner/Component_CurrencyDataTestDialog/Component_Toolbar484.def b/_Main/UI/MacroPlanner/Component_CurrencyDataTestDialog/Component_Toolbar484.def
new file mode 100644
index 0000000..fb1103c
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_CurrencyDataTestDialog/Component_Toolbar484.def
@@ -0,0 +1,70 @@
+Quintiq file version 2.0
+Component Toolbar484
+{
+  #keys: '[414502.0.88134261]'
+  BaseType: 'Toolbar'
+  GBLayout
+  {
+    Type: 'internal[GBLayoutDefinition]'
+    Columns:
+    [
+      GBFlow.Column { grow: 128 id: 486 parent: 0 }
+      GBFlow.Column { grow: 0 id: 661 parent: 0 }
+      GBFlow.Column { grow: 0 id: 550 parent: 0 }
+    ]
+    Elements:
+    [
+      GBElement
+      {
+        Component => btnOk
+        Position { startcolumn: 661 startrow: 337 endcolumn: 661 endrow: 337 }
+      }
+      GBElement
+      {
+        Component => btnCancel
+        Position { startcolumn: 550 startrow: 337 endcolumn: 550 endrow: 337 }
+      }
+    ]
+    Gaps: [ left: 5 right: 5 top: 0 bottom: 0 inner: 5 ]
+    Rows:
+    [
+      GBFlow.Row { grow: 0 id: 337 parent: 0 }
+    ]
+  }
+  Children:
+  [
+    Component btnOk
+    {
+      #keys: '[414502.0.88134278]'
+      BaseType: 'Button'
+      Properties:
+      [
+        LayoutGroup: 'dlgButtons'
+        Shortcut: 'Alt+O'
+        Text: '&OK'
+      ]
+    }
+    Component btnCancel
+    {
+      #keys: '[414502.0.88134286]'
+      BaseType: 'Button'
+      Properties:
+      [
+        LayoutGroup: 'dlgButtons'
+        Shortcut: 'Alt+C'
+        Text: '&Cancel'
+      ]
+    }
+  ]
+  Properties:
+  [
+    Border: false
+    Location: 'bottom'
+    Size: 26
+    ModeledStringList ChildOrdering
+    {
+      c: btnOk
+      c: btnCancel
+    }
+  ]
+}
diff --git a/_Main/UI/MacroPlanner/Component_CurrencyDataTestDialog/Method_OpenDialog.def b/_Main/UI/MacroPlanner/Component_CurrencyDataTestDialog/Method_OpenDialog.def
new file mode 100644
index 0000000..1402dba
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_CurrencyDataTestDialog/Method_OpenDialog.def
@@ -0,0 +1,17 @@
+Quintiq file version 2.0
+#parent: #root
+Method OpenDialog (
+  internal[GUIComponent] parent
+) id:Method_CurrencyDataTestDialog_OpenDialog
+{
+  #keys: '[414502.0.88134527]'
+  Body:
+  [*
+    testResult := MacroPlan.TestDataConnect("TestCurrency");
+    
+    Label413.Text( testResult );
+    
+    
+    this.DoModal( parent );
+  *]
+}
diff --git a/_Main/UI/MacroPlanner/Component_CurrencyDataTestDialog/Response_Toolbar484_btnCancel_OnClick.def b/_Main/UI/MacroPlanner/Component_CurrencyDataTestDialog/Response_Toolbar484_btnCancel_OnClick.def
new file mode 100644
index 0000000..93b5667
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_CurrencyDataTestDialog/Response_Toolbar484_btnCancel_OnClick.def
@@ -0,0 +1,11 @@
+Quintiq file version 2.0
+#parent: Toolbar484/btnCancel
+Response OnClick () id:Response_Toolbar484_btnCancel_OnClick
+{
+  #keys: '[414502.0.88134293]'
+  Body:
+  [*
+    Dialog.EndModal(-1);
+  *]
+  DefinitionID: 'Responsedef_GUIButtonBase_OnClick'
+}
diff --git a/_Main/UI/MacroPlanner/Component_CurrencyDataTestDialog/Response_Toolbar484_btnOk_OnClick.def b/_Main/UI/MacroPlanner/Component_CurrencyDataTestDialog/Response_Toolbar484_btnOk_OnClick.def
new file mode 100644
index 0000000..0dd56ce
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_CurrencyDataTestDialog/Response_Toolbar484_btnOk_OnClick.def
@@ -0,0 +1,12 @@
+Quintiq file version 2.0
+#parent: Toolbar484/btnOk
+Response OnClick () id:Response_Toolbar484_btnOk_OnClick
+{
+  #keys: '[414502.0.88134285]'
+  Body:
+  [*
+    Dialog.ApplyChanges();
+    Dialog.EndModal(1);
+  *]
+  DefinitionID: 'Responsedef_GUIButtonBase_OnClick'
+}
diff --git a/_Main/UI/MacroPlanner/Component_CurrencyDataTestDialog/_ROOT_Component_CurrencyDataTestDialog.def b/_Main/UI/MacroPlanner/Component_CurrencyDataTestDialog/_ROOT_Component_CurrencyDataTestDialog.def
new file mode 100644
index 0000000..b4135a8
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_CurrencyDataTestDialog/_ROOT_Component_CurrencyDataTestDialog.def
@@ -0,0 +1,55 @@
+Quintiq file version 2.0
+#root
+#parent: MacroPlanner
+OrphanComponent CurrencyDataTestDialog
+{
+  #keys: '[414502.0.88134250]'
+  BaseType: 'Dialog'
+  GBLayout
+  {
+    Type: 'internal[GBLayoutDefinition]'
+    Columns:
+    [
+      GBFlow.Column { grow: 0 id: 947 parent: 0 }
+    ]
+    Elements:
+    [
+      GBElement
+      {
+        Component => Label413
+        Position { startcolumn: 947 startrow: 363 endcolumn: 947 endrow: 363 }
+      }
+    ]
+    Gaps: [ left: 10 right: 10 top: 10 bottom: 10 inner: 5 ]
+    Rows:
+    [
+      GBFlow.Row { grow: 0 id: 363 parent: 0 }
+    ]
+  }
+  Children:
+  [
+    #child: Toolbar484
+    Component Label413
+    {
+      #keys: '[414502.0.88134400]'
+      BaseType: 'Label'
+      Properties:
+      [
+        Transparent: true
+      ]
+    }
+  ]
+  Properties:
+  [
+    EnterButton: 'btnOk'
+    EscapeButton: 'btnCancel'
+    Height: 108
+    Title: 'Currency Data Test Dialog'
+    Width: 121
+    ModeledStringList ChildOrdering
+    {
+      c: Toolbar484
+      c: Label413
+    }
+  ]
+}
diff --git a/_Main/UI/MacroPlanner/Component_CurrencyRateDataTestDialog/Component_Toolbar868.def b/_Main/UI/MacroPlanner/Component_CurrencyRateDataTestDialog/Component_Toolbar868.def
new file mode 100644
index 0000000..29de3f7
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_CurrencyRateDataTestDialog/Component_Toolbar868.def
@@ -0,0 +1,70 @@
+Quintiq file version 2.0
+Component Toolbar868
+{
+  #keys: '[414502.0.88134578]'
+  BaseType: 'Toolbar'
+  GBLayout
+  {
+    Type: 'internal[GBLayoutDefinition]'
+    Columns:
+    [
+      GBFlow.Column { grow: 128 id: 376 parent: 0 }
+      GBFlow.Column { grow: 0 id: 118 parent: 0 }
+      GBFlow.Column { grow: 0 id: 500 parent: 0 }
+    ]
+    Elements:
+    [
+      GBElement
+      {
+        Component => btnOk
+        Position { startcolumn: 118 startrow: 254 endcolumn: 118 endrow: 254 }
+      }
+      GBElement
+      {
+        Component => btnCancel
+        Position { startcolumn: 500 startrow: 254 endcolumn: 500 endrow: 254 }
+      }
+    ]
+    Gaps: [ left: 5 right: 5 top: 0 bottom: 0 inner: 5 ]
+    Rows:
+    [
+      GBFlow.Row { grow: 0 id: 254 parent: 0 }
+    ]
+  }
+  Children:
+  [
+    Component btnOk
+    {
+      #keys: '[414502.0.88134595]'
+      BaseType: 'Button'
+      Properties:
+      [
+        LayoutGroup: 'dlgButtons'
+        Shortcut: 'Alt+O'
+        Text: '&OK'
+      ]
+    }
+    Component btnCancel
+    {
+      #keys: '[414502.0.88134603]'
+      BaseType: 'Button'
+      Properties:
+      [
+        LayoutGroup: 'dlgButtons'
+        Shortcut: 'Alt+C'
+        Text: '&Cancel'
+      ]
+    }
+  ]
+  Properties:
+  [
+    Border: false
+    Location: 'bottom'
+    Size: 26
+    ModeledStringList ChildOrdering
+    {
+      c: btnOk
+      c: btnCancel
+    }
+  ]
+}
diff --git a/_Main/UI/MacroPlanner/Component_CurrencyRateDataTestDialog/Method_OpenDialog.def b/_Main/UI/MacroPlanner/Component_CurrencyRateDataTestDialog/Method_OpenDialog.def
new file mode 100644
index 0000000..81ec543
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_CurrencyRateDataTestDialog/Method_OpenDialog.def
@@ -0,0 +1,17 @@
+Quintiq file version 2.0
+#parent: #root
+Method OpenDialog (
+  internal[GUIComponent] parent
+) id:Method_CurrencyRateDataTestDialog_OpenDialog
+{
+  #keys: '[414502.0.88134671]'
+  Body:
+  [*
+    testResult := MacroPlan.TestDataConnect("TestCurrencyRate");
+    
+    Label492.Text( testResult );
+    
+    
+    this.DoModal( parent );
+  *]
+}
diff --git a/_Main/UI/MacroPlanner/Component_CurrencyRateDataTestDialog/Response_Toolbar868_btnCancel_OnClick.def b/_Main/UI/MacroPlanner/Component_CurrencyRateDataTestDialog/Response_Toolbar868_btnCancel_OnClick.def
new file mode 100644
index 0000000..4a3848a
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_CurrencyRateDataTestDialog/Response_Toolbar868_btnCancel_OnClick.def
@@ -0,0 +1,11 @@
+Quintiq file version 2.0
+#parent: Toolbar868/btnCancel
+Response OnClick () id:Response_Toolbar868_btnCancel_OnClick
+{
+  #keys: '[414502.0.88134610]'
+  Body:
+  [*
+    Dialog.EndModal(-1);
+  *]
+  DefinitionID: 'Responsedef_GUIButtonBase_OnClick'
+}
diff --git a/_Main/UI/MacroPlanner/Component_CurrencyRateDataTestDialog/Response_Toolbar868_btnOk_OnClick.def b/_Main/UI/MacroPlanner/Component_CurrencyRateDataTestDialog/Response_Toolbar868_btnOk_OnClick.def
new file mode 100644
index 0000000..f0dc017
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_CurrencyRateDataTestDialog/Response_Toolbar868_btnOk_OnClick.def
@@ -0,0 +1,12 @@
+Quintiq file version 2.0
+#parent: Toolbar868/btnOk
+Response OnClick () id:Response_Toolbar868_btnOk_OnClick
+{
+  #keys: '[414502.0.88134602]'
+  Body:
+  [*
+    Dialog.ApplyChanges();
+    Dialog.EndModal(1);
+  *]
+  DefinitionID: 'Responsedef_GUIButtonBase_OnClick'
+}
diff --git a/_Main/UI/MacroPlanner/Component_CurrencyRateDataTestDialog/_ROOT_Component_CurrencyRateDataTestDialog.def b/_Main/UI/MacroPlanner/Component_CurrencyRateDataTestDialog/_ROOT_Component_CurrencyRateDataTestDialog.def
new file mode 100644
index 0000000..7fefc38
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_CurrencyRateDataTestDialog/_ROOT_Component_CurrencyRateDataTestDialog.def
@@ -0,0 +1,54 @@
+Quintiq file version 2.0
+#root
+#parent: MacroPlanner
+OrphanComponent CurrencyRateDataTestDialog
+{
+  #keys: '[414502.0.88134567]'
+  BaseType: 'Dialog'
+  GBLayout
+  {
+    Type: 'internal[GBLayoutDefinition]'
+    Columns:
+    [
+      GBFlow.Column { grow: 0 id: 116 parent: 0 }
+    ]
+    Elements:
+    [
+      GBElement
+      {
+        Component => Label492
+        Position { startcolumn: 116 startrow: 920 endcolumn: 116 endrow: 920 }
+      }
+    ]
+    Gaps: [ left: 10 right: 10 top: 10 bottom: 10 inner: 5 ]
+    Rows:
+    [
+      GBFlow.Row { grow: 0 id: 920 parent: 0 }
+    ]
+  }
+  Children:
+  [
+    #child: Toolbar868
+    Component Label492
+    {
+      #keys: '[414502.0.88134655]'
+      BaseType: 'Label'
+      Properties:
+      [
+        Transparent: true
+      ]
+    }
+  ]
+  Properties:
+  [
+    EnterButton: 'btnOk'
+    EscapeButton: 'btnCancel'
+    Title: 'Currency Rate Data Test Dialog'
+    Width: 444
+    ModeledStringList ChildOrdering
+    {
+      c: Toolbar868
+      c: Label492
+    }
+  ]
+}
diff --git a/_Main/UI/MacroPlanner/Component_LanesDataTestDialog/Component_Toolbar458.def b/_Main/UI/MacroPlanner/Component_LanesDataTestDialog/Component_Toolbar458.def
new file mode 100644
index 0000000..af42334
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_LanesDataTestDialog/Component_Toolbar458.def
@@ -0,0 +1,70 @@
+Quintiq file version 2.0
+Component Toolbar458
+{
+  #keys: '[414502.0.18234842]'
+  BaseType: 'Toolbar'
+  GBLayout
+  {
+    Type: 'internal[GBLayoutDefinition]'
+    Columns:
+    [
+      GBFlow.Column { grow: 128 id: 178 parent: 0 }
+      GBFlow.Column { grow: 0 id: 729 parent: 0 }
+      GBFlow.Column { grow: 0 id: 210 parent: 0 }
+    ]
+    Elements:
+    [
+      GBElement
+      {
+        Component => btnOk
+        Position { startcolumn: 729 startrow: 251 endcolumn: 729 endrow: 251 }
+      }
+      GBElement
+      {
+        Component => btnCancel
+        Position { startcolumn: 210 startrow: 251 endcolumn: 210 endrow: 251 }
+      }
+    ]
+    Gaps: [ left: 5 right: 5 top: 0 bottom: 0 inner: 5 ]
+    Rows:
+    [
+      GBFlow.Row { grow: 0 id: 251 parent: 0 }
+    ]
+  }
+  Children:
+  [
+    Component btnOk
+    {
+      #keys: '[414502.0.18234859]'
+      BaseType: 'Button'
+      Properties:
+      [
+        LayoutGroup: 'dlgButtons'
+        Shortcut: 'Alt+O'
+        Text: '&OK'
+      ]
+    }
+    Component btnCancel
+    {
+      #keys: '[414502.0.18234867]'
+      BaseType: 'Button'
+      Properties:
+      [
+        LayoutGroup: 'dlgButtons'
+        Shortcut: 'Alt+C'
+        Text: '&Cancel'
+      ]
+    }
+  ]
+  Properties:
+  [
+    Border: false
+    Location: 'bottom'
+    Size: 26
+    ModeledStringList ChildOrdering
+    {
+      c: btnOk
+      c: btnCancel
+    }
+  ]
+}
diff --git a/_Main/UI/MacroPlanner/Component_LanesDataTestDialog/Method_OpenDialog.def b/_Main/UI/MacroPlanner/Component_LanesDataTestDialog/Method_OpenDialog.def
new file mode 100644
index 0000000..e2f983a
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_LanesDataTestDialog/Method_OpenDialog.def
@@ -0,0 +1,17 @@
+Quintiq file version 2.0
+#parent: #root
+Method OpenDialog (
+  internal[GUIComponent] parent
+) id:Method_LanesDataTestDialog_OpenDialog
+{
+  #keys: '[414502.0.27954178]'
+  Body:
+  [*
+    testResult := MacroPlan.TestDataConnect("TestLanes");
+    
+    Label808.Text( testResult );
+    
+    
+    this.DoModal( parent );
+  *]
+}
diff --git a/_Main/UI/MacroPlanner/Component_LanesDataTestDialog/Response_Toolbar458_btnCancel_OnClick.def b/_Main/UI/MacroPlanner/Component_LanesDataTestDialog/Response_Toolbar458_btnCancel_OnClick.def
new file mode 100644
index 0000000..431eab4
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_LanesDataTestDialog/Response_Toolbar458_btnCancel_OnClick.def
@@ -0,0 +1,11 @@
+Quintiq file version 2.0
+#parent: Toolbar458/btnCancel
+Response OnClick () id:Response_Toolbar458_btnCancel_OnClick
+{
+  #keys: '[414502.0.18234874]'
+  Body:
+  [*
+    Dialog.EndModal(-1);
+  *]
+  DefinitionID: 'Responsedef_GUIButtonBase_OnClick'
+}
diff --git a/_Main/UI/MacroPlanner/Component_LanesDataTestDialog/Response_Toolbar458_btnOk_OnClick.def b/_Main/UI/MacroPlanner/Component_LanesDataTestDialog/Response_Toolbar458_btnOk_OnClick.def
new file mode 100644
index 0000000..bb58abf
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_LanesDataTestDialog/Response_Toolbar458_btnOk_OnClick.def
@@ -0,0 +1,12 @@
+Quintiq file version 2.0
+#parent: Toolbar458/btnOk
+Response OnClick () id:Response_Toolbar458_btnOk_OnClick
+{
+  #keys: '[414502.0.18234866]'
+  Body:
+  [*
+    Dialog.ApplyChanges();
+    Dialog.EndModal(1);
+  *]
+  DefinitionID: 'Responsedef_GUIButtonBase_OnClick'
+}
diff --git a/_Main/UI/MacroPlanner/Component_LanesDataTestDialog/_ROOT_Component_LanesDataTestDialog.def b/_Main/UI/MacroPlanner/Component_LanesDataTestDialog/_ROOT_Component_LanesDataTestDialog.def
new file mode 100644
index 0000000..8c6fb22
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_LanesDataTestDialog/_ROOT_Component_LanesDataTestDialog.def
@@ -0,0 +1,55 @@
+Quintiq file version 2.0
+#root
+#parent: MacroPlanner
+OrphanComponent LanesDataTestDialog
+{
+  #keys: '[414502.0.18234831]'
+  BaseType: 'Dialog'
+  GBLayout
+  {
+    Type: 'internal[GBLayoutDefinition]'
+    Columns:
+    [
+      GBFlow.Column { grow: 0 id: 785 parent: 0 }
+    ]
+    Elements:
+    [
+      GBElement
+      {
+        Component => Label808
+        Position { startcolumn: 785 startrow: 325 endcolumn: 785 endrow: 325 }
+      }
+    ]
+    Gaps: [ left: 10 right: 10 top: 10 bottom: 10 inner: 5 ]
+    Rows:
+    [
+      GBFlow.Row { grow: 0 id: 325 parent: 0 }
+    ]
+  }
+  Children:
+  [
+    #child: Toolbar458
+    Component Label808
+    {
+      #keys: '[414502.0.27954099]'
+      BaseType: 'Label'
+      Properties:
+      [
+        Transparent: true
+      ]
+    }
+  ]
+  Properties:
+  [
+    EnterButton: 'btnOk'
+    EscapeButton: 'btnCancel'
+    Height: 108
+    Title: 'Lanes Data Test'
+    Width: 136
+    ModeledStringList ChildOrdering
+    {
+      c: Toolbar458
+      c: Label808
+    }
+  ]
+}
diff --git a/_Main/UI/MacroPlanner/Component_LanesLegsDataTestDialog/Component_Toolbar886.def b/_Main/UI/MacroPlanner/Component_LanesLegsDataTestDialog/Component_Toolbar886.def
new file mode 100644
index 0000000..c42fef1
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_LanesLegsDataTestDialog/Component_Toolbar886.def
@@ -0,0 +1,70 @@
+Quintiq file version 2.0
+Component Toolbar886
+{
+  #keys: '[412960.0.15704261]'
+  BaseType: 'Toolbar'
+  GBLayout
+  {
+    Type: 'internal[GBLayoutDefinition]'
+    Columns:
+    [
+      GBFlow.Column { grow: 128 id: 851 parent: 0 }
+      GBFlow.Column { grow: 0 id: 755 parent: 0 }
+      GBFlow.Column { grow: 0 id: 969 parent: 0 }
+    ]
+    Elements:
+    [
+      GBElement
+      {
+        Component => btnOk
+        Position { startcolumn: 755 startrow: 569 endcolumn: 755 endrow: 569 }
+      }
+      GBElement
+      {
+        Component => btnCancel
+        Position { startcolumn: 969 startrow: 569 endcolumn: 969 endrow: 569 }
+      }
+    ]
+    Gaps: [ left: 5 right: 5 top: 0 bottom: 0 inner: 5 ]
+    Rows:
+    [
+      GBFlow.Row { grow: 0 id: 569 parent: 0 }
+    ]
+  }
+  Children:
+  [
+    Component btnOk
+    {
+      #keys: '[412960.0.15704278]'
+      BaseType: 'Button'
+      Properties:
+      [
+        LayoutGroup: 'dlgButtons'
+        Shortcut: 'Alt+O'
+        Text: '&OK'
+      ]
+    }
+    Component btnCancel
+    {
+      #keys: '[412960.0.15704286]'
+      BaseType: 'Button'
+      Properties:
+      [
+        LayoutGroup: 'dlgButtons'
+        Shortcut: 'Alt+C'
+        Text: '&Cancel'
+      ]
+    }
+  ]
+  Properties:
+  [
+    Border: false
+    Location: 'bottom'
+    Size: 26
+    ModeledStringList ChildOrdering
+    {
+      c: btnOk
+      c: btnCancel
+    }
+  ]
+}
diff --git a/_Main/UI/MacroPlanner/Component_LanesLegsDataTestDialog/Method_OpenDialog.def b/_Main/UI/MacroPlanner/Component_LanesLegsDataTestDialog/Method_OpenDialog.def
new file mode 100644
index 0000000..16abb6c
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_LanesLegsDataTestDialog/Method_OpenDialog.def
@@ -0,0 +1,17 @@
+Quintiq file version 2.0
+#parent: #root
+Method OpenDialog (
+  internal[GUIComponent] parent
+) id:Method_LanesLegsDataTestDialog_OpenDialog
+{
+  #keys: '[412960.0.15704586]'
+  Body:
+  [*
+    testResult := MacroPlan.TestDataConnect("TestLanesLegs");
+    
+    Label484.Text( testResult );
+    
+    
+    this.DoModal( parent );
+  *]
+}
diff --git a/_Main/UI/MacroPlanner/Component_LanesLegsDataTestDialog/Response_Toolbar886_btnCancel_OnClick.def b/_Main/UI/MacroPlanner/Component_LanesLegsDataTestDialog/Response_Toolbar886_btnCancel_OnClick.def
new file mode 100644
index 0000000..ba4cc61
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_LanesLegsDataTestDialog/Response_Toolbar886_btnCancel_OnClick.def
@@ -0,0 +1,11 @@
+Quintiq file version 2.0
+#parent: Toolbar886/btnCancel
+Response OnClick () id:Response_Toolbar886_btnCancel_OnClick
+{
+  #keys: '[412960.0.15704293]'
+  Body:
+  [*
+    Dialog.EndModal(-1);
+  *]
+  DefinitionID: 'Responsedef_GUIButtonBase_OnClick'
+}
diff --git a/_Main/UI/MacroPlanner/Component_LanesLegsDataTestDialog/Response_Toolbar886_btnOk_OnClick.def b/_Main/UI/MacroPlanner/Component_LanesLegsDataTestDialog/Response_Toolbar886_btnOk_OnClick.def
new file mode 100644
index 0000000..0928340
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_LanesLegsDataTestDialog/Response_Toolbar886_btnOk_OnClick.def
@@ -0,0 +1,12 @@
+Quintiq file version 2.0
+#parent: Toolbar886/btnOk
+Response OnClick () id:Response_Toolbar886_btnOk_OnClick
+{
+  #keys: '[412960.0.15704285]'
+  Body:
+  [*
+    Dialog.ApplyChanges();
+    Dialog.EndModal(1);
+  *]
+  DefinitionID: 'Responsedef_GUIButtonBase_OnClick'
+}
diff --git a/_Main/UI/MacroPlanner/Component_LanesLegsDataTestDialog/_ROOT_Component_LanesLegsDataTestDialog.def b/_Main/UI/MacroPlanner/Component_LanesLegsDataTestDialog/_ROOT_Component_LanesLegsDataTestDialog.def
new file mode 100644
index 0000000..4b4e5a1
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_LanesLegsDataTestDialog/_ROOT_Component_LanesLegsDataTestDialog.def
@@ -0,0 +1,54 @@
+Quintiq file version 2.0
+#root
+#parent: MacroPlanner
+OrphanComponent LanesLegsDataTestDialog
+{
+  #keys: '[412960.0.15704249]'
+  BaseType: 'Dialog'
+  GBLayout
+  {
+    Type: 'internal[GBLayoutDefinition]'
+    Columns:
+    [
+      GBFlow.Column { grow: 0 id: 739 parent: 0 }
+    ]
+    Elements:
+    [
+      GBElement
+      {
+        Component => Label484
+        Position { startcolumn: 739 startrow: 321 endcolumn: 739 endrow: 321 }
+      }
+    ]
+    Gaps: [ left: 10 right: 10 top: 10 bottom: 10 inner: 5 ]
+    Rows:
+    [
+      GBFlow.Row { grow: 0 id: 321 parent: 0 }
+    ]
+  }
+  Children:
+  [
+    #child: Toolbar886
+    Component Label484
+    {
+      #keys: '[412960.0.15704489]'
+      BaseType: 'Label'
+      Properties:
+      [
+        Transparent: true
+      ]
+    }
+  ]
+  Properties:
+  [
+    EnterButton: 'btnOk'
+    EscapeButton: 'btnCancel'
+    Title: 'Lanes Legs Data Test'
+    Width: 492
+    ModeledStringList ChildOrdering
+    {
+      c: Toolbar886
+      c: Label484
+    }
+  ]
+}
diff --git a/_Main/UI/MacroPlanner/Component_StockpointDataTestDialog/Component_Toolbar309.def b/_Main/UI/MacroPlanner/Component_StockpointDataTestDialog/Component_Toolbar309.def
new file mode 100644
index 0000000..ef7dbeb
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_StockpointDataTestDialog/Component_Toolbar309.def
@@ -0,0 +1,70 @@
+Quintiq file version 2.0
+Component Toolbar309
+{
+  #keys: '[414502.0.18234549]'
+  BaseType: 'Toolbar'
+  GBLayout
+  {
+    Type: 'internal[GBLayoutDefinition]'
+    Columns:
+    [
+      GBFlow.Column { grow: 128 id: 557 parent: 0 }
+      GBFlow.Column { grow: 0 id: 351 parent: 0 }
+      GBFlow.Column { grow: 0 id: 110 parent: 0 }
+    ]
+    Elements:
+    [
+      GBElement
+      {
+        Component => btnOk
+        Position { startcolumn: 351 startrow: 960 endcolumn: 351 endrow: 960 }
+      }
+      GBElement
+      {
+        Component => btnCancel
+        Position { startcolumn: 110 startrow: 960 endcolumn: 110 endrow: 960 }
+      }
+    ]
+    Gaps: [ left: 5 right: 5 top: 0 bottom: 0 inner: 5 ]
+    Rows:
+    [
+      GBFlow.Row { grow: 0 id: 960 parent: 0 }
+    ]
+  }
+  Children:
+  [
+    Component btnOk
+    {
+      #keys: '[414502.0.18234566]'
+      BaseType: 'Button'
+      Properties:
+      [
+        LayoutGroup: 'dlgButtons'
+        Shortcut: 'Alt+O'
+        Text: '&OK'
+      ]
+    }
+    Component btnCancel
+    {
+      #keys: '[414502.0.18234574]'
+      BaseType: 'Button'
+      Properties:
+      [
+        LayoutGroup: 'dlgButtons'
+        Shortcut: 'Alt+C'
+        Text: '&Cancel'
+      ]
+    }
+  ]
+  Properties:
+  [
+    Border: false
+    Location: 'bottom'
+    Size: 26
+    ModeledStringList ChildOrdering
+    {
+      c: btnOk
+      c: btnCancel
+    }
+  ]
+}
diff --git a/_Main/UI/MacroPlanner/Component_StockpointDataTestDialog/Method_OpenDialog.def b/_Main/UI/MacroPlanner/Component_StockpointDataTestDialog/Method_OpenDialog.def
new file mode 100644
index 0000000..9019ae7
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_StockpointDataTestDialog/Method_OpenDialog.def
@@ -0,0 +1,17 @@
+Quintiq file version 2.0
+#parent: #root
+Method OpenDialog (
+  internal[GUIComponent] parent
+) id:Method_StockpointDataTestDialog_OpenDialog
+{
+  #keys: '[414502.0.18237141]'
+  Body:
+  [*
+    testResult := MacroPlan.TestDataConnect("TestStockpoint");
+    
+    Label310.Text( testResult );
+    
+    
+    this.DoModal( parent );
+  *]
+}
diff --git a/_Main/UI/MacroPlanner/Component_StockpointDataTestDialog/Response_Toolbar309_btnCancel_OnClick.def b/_Main/UI/MacroPlanner/Component_StockpointDataTestDialog/Response_Toolbar309_btnCancel_OnClick.def
new file mode 100644
index 0000000..e57510c
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_StockpointDataTestDialog/Response_Toolbar309_btnCancel_OnClick.def
@@ -0,0 +1,11 @@
+Quintiq file version 2.0
+#parent: Toolbar309/btnCancel
+Response OnClick () id:Response_Toolbar309_btnCancel_OnClick
+{
+  #keys: '[414502.0.18234581]'
+  Body:
+  [*
+    Dialog.EndModal(-1);
+  *]
+  DefinitionID: 'Responsedef_GUIButtonBase_OnClick'
+}
diff --git a/_Main/UI/MacroPlanner/Component_StockpointDataTestDialog/Response_Toolbar309_btnOk_OnClick.def b/_Main/UI/MacroPlanner/Component_StockpointDataTestDialog/Response_Toolbar309_btnOk_OnClick.def
new file mode 100644
index 0000000..2b3730d
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_StockpointDataTestDialog/Response_Toolbar309_btnOk_OnClick.def
@@ -0,0 +1,12 @@
+Quintiq file version 2.0
+#parent: Toolbar309/btnOk
+Response OnClick () id:Response_Toolbar309_btnOk_OnClick
+{
+  #keys: '[414502.0.18234573]'
+  Body:
+  [*
+    Dialog.ApplyChanges();
+    Dialog.EndModal(1);
+  *]
+  DefinitionID: 'Responsedef_GUIButtonBase_OnClick'
+}
diff --git a/_Main/UI/MacroPlanner/Component_StockpointDataTestDialog/_ROOT_Component_StockpointDataTestDialog.def b/_Main/UI/MacroPlanner/Component_StockpointDataTestDialog/_ROOT_Component_StockpointDataTestDialog.def
new file mode 100644
index 0000000..0aadd85
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_StockpointDataTestDialog/_ROOT_Component_StockpointDataTestDialog.def
@@ -0,0 +1,55 @@
+Quintiq file version 2.0
+#root
+#parent: MacroPlanner
+OrphanComponent StockpointDataTestDialog
+{
+  #keys: '[414502.0.18234537]'
+  BaseType: 'Dialog'
+  GBLayout
+  {
+    Type: 'internal[GBLayoutDefinition]'
+    Columns:
+    [
+      GBFlow.Column { grow: 0 id: 423 parent: 0 }
+    ]
+    Elements:
+    [
+      GBElement
+      {
+        Component => Label310
+        Position { startcolumn: 423 startrow: 569 endcolumn: 423 endrow: 569 }
+      }
+    ]
+    Gaps: [ left: 10 right: 10 top: 10 bottom: 10 inner: 5 ]
+    Rows:
+    [
+      GBFlow.Row { grow: 0 id: 569 parent: 0 }
+    ]
+  }
+  Children:
+  [
+    #child: Toolbar309
+    Component Label310
+    {
+      #keys: '[414502.0.18237441]'
+      BaseType: 'Label'
+      Properties:
+      [
+        Transparent: true
+      ]
+    }
+  ]
+  Properties:
+  [
+    EnterButton: 'btnOk'
+    EscapeButton: 'btnCancel'
+    Height: 108
+    Title: 'Stockpoint Data Test'
+    Width: 121
+    ModeledStringList ChildOrdering
+    {
+      c: Label310
+      c: Toolbar309
+    }
+  ]
+}
diff --git a/_var/_Main/Data/.keep b/_var/_Main/Data/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/_var/_Main/Data/.keep
diff --git a/_var/_Main/KBs/MacroPlanner/ScenarioManager/KB/1.0.0.0/Change_1086.kbc b/_var/_Main/KBs/MacroPlanner/ScenarioManager/KB/1.0.0.0/Change_1086.kbc
new file mode 100644
index 0000000..775e999
--- /dev/null
+++ b/_var/_Main/KBs/MacroPlanner/ScenarioManager/KB/1.0.0.0/Change_1086.kbc
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<KBSChange:KBSChange  
+  xmlns:KBSChange="KBSChange"
+  xmlns:KBRevisionElementID="KBRevisionElementID"
+  xmlns:KBElementID="KBElementID">
+  <KBSChange:ChangeNr>1086</KBSChange:ChangeNr>
+  <KBSChange:User>quintiq/yypsybs</KBSChange:User>
+  <KBSChange:Description>123</KBSChange:Description>
+  <KBSChange:Category></KBSChange:Category>
+  <KBSChange:CreationTime>2023-08-24T14:48:03</KBSChange:CreationTime>
+  <KBSChange:Elements>
+    <KBRevisionElementID:KBRevisionElementID>
+      <KBRevisionElementID:Revision>45</KBRevisionElementID:Revision>
+      <KBElementID:KBElementID>
+        <KBElementID:Kind>Table</KBElementID:Kind>
+        <KBElementID:Name>AccountTypes</KBElementID:Name>
+      </KBElementID:KBElementID>
+    </KBRevisionElementID:KBRevisionElementID>
+    <KBRevisionElementID:KBRevisionElementID>
+      <KBRevisionElementID:Revision>1</KBRevisionElementID:Revision>
+      <KBElementID:KBElementID>
+        <KBElementID:Kind>Table</KBElementID:Kind>
+        <KBElementID:Name>BusinessTypes</KBElementID:Name>
+      </KBElementID:KBElementID>
+    </KBRevisionElementID:KBRevisionElementID>
+    <KBRevisionElementID:KBRevisionElementID>
+      <KBRevisionElementID:Revision>47</KBRevisionElementID:Revision>
+      <KBElementID:KBElementID>
+        <KBElementID:Kind>Table</KBElementID:Kind>
+        <KBElementID:Name>CostDriverRules</KBElementID:Name>
+      </KBElementID:KBElementID>
+    </KBRevisionElementID:KBRevisionElementID>
+    <KBRevisionElementID:KBRevisionElementID>
+      <KBRevisionElementID:Revision>17</KBRevisionElementID:Revision>
+      <KBElementID:KBElementID>
+        <KBElementID:Kind>Table</KBElementID:Kind>
+        <KBElementID:Name>DemoScenario</KBElementID:Name>
+      </KBElementID:KBElementID>
+    </KBRevisionElementID:KBRevisionElementID>
+    <KBRevisionElementID:KBRevisionElementID>
+      <KBRevisionElementID:Revision>57</KBRevisionElementID:Revision>
+      <KBElementID:KBElementID>
+        <KBElementID:Kind>Table</KBElementID:Kind>
+        <KBElementID:Name>NonFinancialKPI</KBElementID:Name>
+      </KBElementID:KBElementID>
+    </KBRevisionElementID:KBRevisionElementID>
+    <KBRevisionElementID:KBRevisionElementID>
+      <KBRevisionElementID:Revision>31</KBRevisionElementID:Revision>
+      <KBElementID:KBElementID>
+        <KBElementID:Kind>Table</KBElementID:Kind>
+        <KBElementID:Name>SanityCheckCategories</KBElementID:Name>
+      </KBElementID:KBElementID>
+    </KBRevisionElementID:KBRevisionElementID>
+    <KBRevisionElementID:KBRevisionElementID>
+      <KBRevisionElementID:Revision>23</KBRevisionElementID:Revision>
+      <KBElementID:KBElementID>
+        <KBElementID:Kind>Table</KBElementID:Kind>
+        <KBElementID:Name>ScenarioStatus</KBElementID:Name>
+      </KBElementID:KBElementID>
+    </KBRevisionElementID:KBRevisionElementID>
+    <KBRevisionElementID:KBRevisionElementID>
+      <KBRevisionElementID:Revision>60</KBRevisionElementID:Revision>
+      <KBElementID:KBElementID>
+        <KBElementID:Kind>Table</KBElementID:Kind>
+        <KBElementID:Name>SolverSettings</KBElementID:Name>
+      </KBElementID:KBElementID>
+    </KBRevisionElementID:KBRevisionElementID>
+    <KBRevisionElementID:KBRevisionElementID>
+      <KBRevisionElementID:Revision>532</KBRevisionElementID:Revision>
+      <KBElementID:KBElementID>
+        <KBElementID:Kind>Table</KBElementID:Kind>
+        <KBElementID:Name>TestInstances</KBElementID:Name>
+      </KBElementID:KBElementID>
+    </KBRevisionElementID:KBRevisionElementID>
+  </KBSChange:Elements>
+</KBSChange:KBSChange>
diff --git a/_var/_Main/KBs/MacroPlanner/ScenarioManager/KB/1.0.0.0/Table_BusinessTypes_1.elm b/_var/_Main/KBs/MacroPlanner/ScenarioManager/KB/1.0.0.0/Table_BusinessTypes_1.elm
new file mode 100644
index 0000000..4ec4fb5
--- /dev/null
+++ b/_var/_Main/KBs/MacroPlanner/ScenarioManager/KB/1.0.0.0/Table_BusinessTypes_1.elm
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<KBSElementRevision:KBSElementRevision  
+  xmlns:KBSElementRevision="KBSElementRevision"
+  xmlns:KBElementID="KBElementID">
+  <KBSElementRevision:Revision>1</KBSElementRevision:Revision>
+  <KBElementID:KBElementID>
+    <KBElementID:Kind>Table</KBElementID:Kind>
+    <KBElementID:Name>BusinessTypes</KBElementID:Name>
+  </KBElementID:KBElementID>
+</KBSElementRevision:KBSElementRevision>
diff --git a/_var/_Main/KBs/MacroPlanner/ScenarioManager/KB/1.0.0.0/Table_BusinessTypes_1.xml b/_var/_Main/KBs/MacroPlanner/ScenarioManager/KB/1.0.0.0/Table_BusinessTypes_1.xml
new file mode 100644
index 0000000..cd052a9
--- /dev/null
+++ b/_var/_Main/KBs/MacroPlanner/ScenarioManager/KB/1.0.0.0/Table_BusinessTypes_1.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<table>
+  <name>BusinessTypes</name>
+  <column>
+    <name>BusinessType</name>
+    <label>BusinessType</label>
+    <type>String</type>
+    <cell value="aaa"/>
+    <cell value="bbb"/>
+  </column>
+</table>

--
Gitblit v1.9.3