From 46ddfed5009f83c7238e11254154c03aa8260774 Mon Sep 17 00:00:00 2001
From: lihongji <3117313295@qq.com>
Date: 星期五, 27 九月 2024 10:15:11 +0800
Subject: [PATCH] 下线计划优化

---
 _Main/BL/Type_OfflinePlanImportData/_ROOT_Type_OfflinePlanImportData.qbl                                            |    9 
 _Main/BL/Type_OfflinePlanImportData/Attribute_Date.qbl                                                              |    7 
 _Main/BL/Type_OfflinePlanImportData/StaticMethod_UpdateCell.qbl                                                     |   31 ++
 _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bImport_OnClick.def                     |   45 +++
 _Main/BL/Type_OfflinePlanCell/Method_QuantityGreaterThan0.qbl                                                       |    9 
 _Main/BL/Type_OfflinePlanImportData/Attribute_Quantity.qbl                                                          |    7 
 _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Component_MatrixEditor951.def                                 |    9 
 _Main/BL/Relations/Relation_OfflinePlanCell_OfflinePlanColumn_OfflinePlanColumn_OfflinePlanCell.qbl                 |    2 
 _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Component_pHeader.def                                         |   65 ----
 _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bDownload_OnClick.def                   |   22 +
 _Main/Sys/Repr/Global/OfflinePlanCell.qrp                                                                           |   21 +
 _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bRestore_OnClick.def                    |    6 
 _Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Component_mbMainMenu.def                                 |    4 
 _Main/UI/MacroPlanner/Component_frmStandardAnalysis627/_ROOT_Component_frmStandardAnalysis627.def                   |   16 +
 _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bRefresh_OnClick.def                    |    6 
 _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/_ROOT_Component_FormOfflinePlan.def                           |    2 
 _Main/UI/MacroPlanner/Component_frmStandardAnalysis627/Component_swTop.def                                          |   29 ++
 _Main/BL/Relations/Relation_OfflinePlanImportData_MacroPlan_MacroPlan_OfflinePlanImportData.qbl                     |   23 +
 _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bSaveAsDraft_OnClick.def                |    6 
 _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bDeductionOfReplacementLoss_OnClick.def |    6 
 _Main/BL/Type_OfflinePlanColumn/DefaultValue_IsShow.qbl                                                             |    7 
 _Main/BL/Type_OfflinePlanCell/Function_CalcQuantity.qbl                                                             |   14 +
 _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bConfirm_OnClick.def                    |    6 
 _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Component_pHeader1#799.def                                    |   85 ++++++
 _Main/BL/Type_OfflinePlanColumn/Attribute_IsShow.qbl                                                                |    7 
 _Main/UI/MacroPlanner/Component_frmStandardAnalysis627/Component_swTopMost.def                                      |   20 +
 _Main/BL/Type_OfflinePlanCell/StaticMethod_Download.qbl                                                             |    7 
 _Main/BL/Type_OfflinePlanCell/Attribute_IsQuantity.qbl                                                              |    7 
 _Main/BL/Type_OfflinePlanImportData/Attribute_ProductID.qbl                                                         |    7 
 _Main/BL/Type_OfflinePlanRow/Attribute_Notes.qbl                                                                    |    1 
 /dev/null                                                                                                           |   22 -
 _Main/BL/Relations/Relation_OfflinePlanCell_OfflinePlanRow_OfflinePlanRow_OfflinePlanCell.qbl                       |    2 
 _Main/BL/Type_OfflinePlanColumn/Function_CalcColumnIndex.qbl                                                        |   13 +
 _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Component_pContent#611.def                                    |   27 ++
 _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Component_pHeader2.def                                        |   25 +
 _Main/BL/Type_OfflinePlanCell/Function_CalcIsQuantity.qbl                                                           |   13 +
 _Main/BL/Type_OfflinePlanImportData/StaticMethod_Upload.qbl                                                         |   66 +++++
 _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader2_sDateFilter_OnUserChanged.def               |   26 ++
 _Main/BL/Type_OfflinePlanCell/StaticMethod_RefreshOfflinePlan.qbl                                                   |   75 +++--
 _Main/BL/Type_OfflinePlanImportData/Attribute_Order.qbl                                                             |    7 
 40 files changed, 616 insertions(+), 146 deletions(-)

diff --git a/_Main/BL/Relations/Relation_OfflinePlanCell_OfflinePlanColumn_OfflinePlanColumn_OfflinePlanCell.qbl b/_Main/BL/Relations/Relation_OfflinePlanCell_OfflinePlanColumn_OfflinePlanColumn_OfflinePlanCell.qbl
index 44c130e..1966dbf 100644
--- a/_Main/BL/Relations/Relation_OfflinePlanCell_OfflinePlanColumn_OfflinePlanColumn_OfflinePlanCell.qbl
+++ b/_Main/BL/Relations/Relation_OfflinePlanCell_OfflinePlanColumn_OfflinePlanColumn_OfflinePlanCell.qbl
@@ -18,6 +18,6 @@
     #keys: '3[413988.0.1296697094][413988.0.1296697093][413988.0.1296697095]'
     Cardinality: '1toN'
     ObjectDefinition: OfflinePlanColumn
-    OwningSide: 'Owned'
+    OwningSide: 'Reference'
   }
 }
diff --git a/_Main/BL/Relations/Relation_OfflinePlanCell_OfflinePlanRow_OfflinePlanRow_OfflinePlanCell.qbl b/_Main/BL/Relations/Relation_OfflinePlanCell_OfflinePlanRow_OfflinePlanRow_OfflinePlanCell.qbl
index dfd7e00..68171d0 100644
--- a/_Main/BL/Relations/Relation_OfflinePlanCell_OfflinePlanRow_OfflinePlanRow_OfflinePlanCell.qbl
+++ b/_Main/BL/Relations/Relation_OfflinePlanCell_OfflinePlanRow_OfflinePlanRow_OfflinePlanCell.qbl
@@ -18,6 +18,6 @@
     #keys: '3[413988.0.1296697107][413988.0.1296697106][413988.0.1296697108]'
     Cardinality: '1toN'
     ObjectDefinition: OfflinePlanRow
-    OwningSide: 'Reference'
+    OwningSide: 'Owned'
   }
 }
diff --git a/_Main/BL/Relations/Relation_OfflinePlanImportData_MacroPlan_MacroPlan_OfflinePlanImportData.qbl b/_Main/BL/Relations/Relation_OfflinePlanImportData_MacroPlan_MacroPlan_OfflinePlanImportData.qbl
new file mode 100644
index 0000000..1c92a84
--- /dev/null
+++ b/_Main/BL/Relations/Relation_OfflinePlanImportData_MacroPlan_MacroPlan_OfflinePlanImportData.qbl
@@ -0,0 +1,23 @@
+Quintiq file version 2.0
+#parent: #root
+Relation OfflinePlanImportData_MacroPlan_MacroPlan_OfflinePlanImportData
+{
+  #keys: '1[413988.0.1558681405]'
+  DefaultRelationStrategy
+  {
+  }
+  RelationSide.LeftSide MacroPlan
+  {
+    #keys: '3[413988.0.1558681407][413988.0.1558681406][413988.0.1558681408]'
+    Cardinality: '0to1'
+    ObjectDefinition: OfflinePlanImportData
+    OwningSide: 'Reference'
+  }
+  RelationSide.RightSide OfflinePlanImportData
+  {
+    #keys: '3[413988.0.1558681410][413988.0.1558681409][413988.0.1558681411]'
+    Cardinality: '1toN'
+    ObjectDefinition: MacroPlan
+    OwningSide: 'Owned'
+  }
+}
diff --git a/_Main/BL/Type_OfflinePlanCell/Attribute_IsQuantity.qbl b/_Main/BL/Type_OfflinePlanCell/Attribute_IsQuantity.qbl
new file mode 100644
index 0000000..3f8f7a2
--- /dev/null
+++ b/_Main/BL/Type_OfflinePlanCell/Attribute_IsQuantity.qbl
@@ -0,0 +1,7 @@
+Quintiq file version 2.0
+#parent: #root
+Attribute IsQuantity
+{
+  #keys: '3[413988.0.1565814440][413988.0.1565814439][413988.0.1565814441]'
+  ValueType: Boolean
+}
diff --git a/_Main/BL/Type_OfflinePlanCell/Function_CalcIsQuantity.qbl b/_Main/BL/Type_OfflinePlanCell/Function_CalcIsQuantity.qbl
new file mode 100644
index 0000000..eef4ef2
--- /dev/null
+++ b/_Main/BL/Type_OfflinePlanCell/Function_CalcIsQuantity.qbl
@@ -0,0 +1,13 @@
+Quintiq file version 2.0
+#parent: #root
+Function CalcIsQuantity
+{
+  TextBody:
+  [*
+    // lihongji Sep-27-2024 (created)
+    
+    value := ifexpr( this.OfflinePlanRow().Type() = "1" and this.OfflinePlanColumn().ColumnIndex() > 1 and this.Quantity() > 0, true, false );
+    
+    this.IsQuantity( value );
+  *]
+}
diff --git a/_Main/BL/Type_OfflinePlanCell/Function_CalcQuantity.qbl b/_Main/BL/Type_OfflinePlanCell/Function_CalcQuantity.qbl
new file mode 100644
index 0000000..9a7da92
--- /dev/null
+++ b/_Main/BL/Type_OfflinePlanCell/Function_CalcQuantity.qbl
@@ -0,0 +1,14 @@
+Quintiq file version 2.0
+#parent: #root
+Function CalcQuantity
+{
+  TextBody:
+  [*
+    // lihongji Sep-27-2024 (created)
+    
+    value := ifexpr( ( this.OfflinePlanRow().Type() = "1" or this.OfflinePlanRow().Type() = "2" ) and this.OfflinePlanColumn().ColumnIndex() > 1, 
+                     guard( [Number]this.Value(), 0 ), 0 );
+    
+    this.Quantity( value );
+  *]
+}
diff --git a/_Main/BL/Type_OfflinePlanCell/Method_QuantityGreaterThan0.qbl b/_Main/BL/Type_OfflinePlanCell/Method_QuantityGreaterThan0.qbl
new file mode 100644
index 0000000..f5715e6
--- /dev/null
+++ b/_Main/BL/Type_OfflinePlanCell/Method_QuantityGreaterThan0.qbl
@@ -0,0 +1,9 @@
+Quintiq file version 2.0
+#parent: #root
+Method QuantityGreaterThan0 (
+  String type,
+  String pl
+) as Boolean
+{
+  TextBody: 'return this.OfflinePlanRow().Type() = type and this.OfflinePlanRow().ProductionLine() = pl and this.Quantity() > 0.0;'
+}
diff --git a/_Main/BL/Type_OfflinePlanCell/StaticMethod_Download.qbl b/_Main/BL/Type_OfflinePlanCell/StaticMethod_Download.qbl
index d9685ab..b91c95f 100644
--- a/_Main/BL/Type_OfflinePlanCell/StaticMethod_Download.qbl
+++ b/_Main/BL/Type_OfflinePlanCell/StaticMethod_Download.qbl
@@ -1,7 +1,8 @@
 Quintiq file version 2.0
 #parent: #root
 StaticMethod Download (
-  MacroPlan macroPlan
+  MacroPlan macroPlan,
+  OfflinePlanRows selectedOPRs
 ) as BinaryValue
 {
   TextBody:
@@ -13,12 +14,12 @@
     
     opt  := maxselect( macroPlan, OfflinePlanTable, tempOPT, true, tempOPT.SaveDateTime() );
     opcs := selectsortedset( opt, OfflinePlanColumn, tempOPC, true, tempOPC.ColumnDate() );
-    oprs := selectsortedset( opt, OfflinePlanRow, tempOPR, true, tempOPR.ProductionLine(), tempOPR.ProductID(), tempOPR.Type() );
+    oprs := selectsortedset( selectedOPRs, Elements, tempOPR, true, tempOPR.ProductionLine(), tempOPR.ProductID(), tempOPR.Type() );
     traverse ( opcs, Elements, opc ) {
       column := xmlDOM.CreateElement( "column" );
       name   := xmlDOM.CreateElement( "name" );
       type   := xmlDOM.CreateElement( "type" );
-      name.TextContent( ifexpr( opc.ColumnDate() < macroPlan.StartOfPlanning().Date(), "", opc.ColumnDate().Format( "Y/M2/D2" ) ) );
+      name.TextContent( ifexpr( opc.ColumnDate() < macroPlan.StartOfPlanning().Date(), "*", opc.ColumnDate().Format( "Y/M2/D2" ) ) );
       type.TextContent( "String" );
       column.AppendChild( name );
       column.AppendChild( type );
diff --git a/_Main/BL/Type_OfflinePlanCell/StaticMethod_RefreshOfflinePlan.qbl b/_Main/BL/Type_OfflinePlanCell/StaticMethod_RefreshOfflinePlan.qbl
index ee04590..131d267 100644
--- a/_Main/BL/Type_OfflinePlanCell/StaticMethod_RefreshOfflinePlan.qbl
+++ b/_Main/BL/Type_OfflinePlanCell/StaticMethod_RefreshOfflinePlan.qbl
@@ -35,12 +35,13 @@
           }
           
           // 璧嬪�煎崟鍏冩牸
-          cellQuantity := opc.OfflinePlanCell( relnew, Value := [String]ns.Quantity().Round( 0 ), Shift := ns.PeriodTask_MP().UnitPeriod().astype( UnitPeriodTimeBase ).ShiftPattern().Name(), Quantity := ns.Quantity() );
-          cellQuantity.OfflinePlanRow( relset, oprQuantity );
-          cellOrder := opc.OfflinePlanCell( relnew, Value := "鍗曞彿" + [String]ns.Quantity().Round( 0 ) + "_" + [String]( ns.ProductInStockingPointInPeriodPlanningLeaf().InventoryLevelEnd() - ns.ProductInStockingPointInPeriodPlanningLeaf().MinInventoryLevel() ), 
-                                            Quantity := ns.Quantity(), 
-                                            InventoryWeight := ns.ProductInStockingPointInPeriodPlanningLeaf().InventoryLevelEnd() - ns.ProductInStockingPointInPeriodPlanningLeaf().MinInventoryLevel() );
-          cellOrder.OfflinePlanRow( relset, oprOrder );
+          cellQuantity := oprQuantity.OfflinePlanCell( relnew, Value := [String]ns.Quantity().Round( 0 ), Shift := ns.PeriodTask_MP().UnitPeriod().astype( UnitPeriodTimeBase ).ShiftPattern().Name() );
+          cellQuantity.OfflinePlanColumn( relset, opc );
+          cellOrder := oprOrder.OfflinePlanCell( relnew, 
+    //                                             Value := "鍗曞彿" + [String]ns.Quantity().Round( 0 ) + "_" + [String]( ns.ProductInStockingPointInPeriodPlanningLeaf().InventoryLevelEnd() - ns.ProductInStockingPointInPeriodPlanningLeaf().MinInventoryLevel() ),
+                                                 Value := [String]ns.Quantity().Round( 0 ),
+                                                 InventoryWeight := ns.ProductInStockingPointInPeriodPlanningLeaf().InventoryLevelEnd() - ns.ProductInStockingPointInPeriodPlanningLeaf().MinInventoryLevel() );
+          cellOrder.OfflinePlanColumn( relset, opc );
         }
       }
       
@@ -59,30 +60,30 @@
     typeOPC    := opt.OfflinePlanColumn( relnew, ColumnDate := macroPlan.StartOfPlanning().Date() - 1 );
     traverse ( opt, OfflinePlanRow, opr ) {
       if ( opr.Type() = "0" ) {
-        productLineCell := productOPC.OfflinePlanCell( relnew, Value := opr.ProductionLine() );
-        productLineCell.OfflinePlanRow( relset, opr );
+        productLineCell := opr.OfflinePlanCell( relnew, Value := opr.ProductionLine() );
+        productLineCell.OfflinePlanColumn( relset, productOPC );
       } else if( opr.Type() = "1" ) {
-        productCell := productOPC.OfflinePlanCell( relnew, Value := opr.ProductID() + ifexpr( opr.Notes() = "", "", "-" + opr.Notes() ) );
-        productCell.OfflinePlanRow( relset, opr );
-        typeCell    := typeOPC.OfflinePlanCell( relnew, Value :=  "Quantity" );
-        typeCell.OfflinePlanRow( relset, opr );
+        productCell := opr.OfflinePlanCell( relnew, Value := opr.ProductID() + ifexpr( opr.Notes() = "", "", "-" + opr.Notes() ) );
+        productCell.OfflinePlanColumn( relset, productOPC );
+        typeCell    := opr.OfflinePlanCell( relnew, Value :=  "Quantity" );
+        typeCell.OfflinePlanColumn( relset, typeOPC );
       } else if ( opr.Type() = "2" ) {
-        typeCell    := typeOPC.OfflinePlanCell( relnew, Value :=  "Order" );
-        typeCell.OfflinePlanRow( relset, opr );
+        typeCell    := opr.OfflinePlanCell( relnew, Value :=  "Order" );
+        typeCell.OfflinePlanColumn( relset, typeOPC );
       } else if ( opr.Type() = "3" ) {
-        totalCell := productOPC.OfflinePlanCell( relnew, Value := "鍚堣" );
-        totalCell.OfflinePlanRow( relset, opr );
-        totalCell := typeOPC.OfflinePlanCell( relnew, Value :=  "鎬婚噺" );
-        totalCell.OfflinePlanRow( relset, opr );
+        totalCell := opr.OfflinePlanCell( relnew, Value := "鍚堣" );
+        totalCell.OfflinePlanColumn( relset, productOPC );
+        totalCell := opr.OfflinePlanCell( relnew, Value :=  "鎬婚噺" );
+        totalCell.OfflinePlanColumn( relset, typeOPC );
       } else if ( opr.Type() = "4" ) {
-        shiftCell := typeOPC.OfflinePlanCell( relnew, Value :=  "鐝" );
-        shiftCell.OfflinePlanRow( relset, opr );
+        shiftCell := opr.OfflinePlanCell( relnew, Value :=  "鐝" );
+        shiftCell.OfflinePlanColumn( relset, typeOPC );
       } else if ( opr.Type() = "5" ) {
-        shiftStartDateCell := typeOPC.OfflinePlanCell( relnew, Value :=  "鐝寮�濮嬫椂闂�" );
-        shiftStartDateCell.OfflinePlanRow( relset, opr );
+        shiftStartDateCell := opr.OfflinePlanCell( relnew, Value :=  "鐝寮�濮嬫椂闂�" );
+        shiftStartDateCell.OfflinePlanColumn( relset, typeOPC );
       } else if ( opr.Type() = "6" ) {
-        shiftEndDateCell := typeOPC.OfflinePlanCell( relnew, Value :=  "鐝缁撴潫鏃堕棿" );
-        shiftEndDateCell.OfflinePlanRow( relset, opr );
+        shiftEndDateCell := opr.OfflinePlanCell( relnew, Value :=  "鐝缁撴潫鏃堕棿" );
+        shiftEndDateCell.OfflinePlanColumn( relset, typeOPC );
       }
     }
     
@@ -95,16 +96,16 @@
       // 琛ュ叏鎬婚噺
       traverse ( totalOPRs, Elements, totalOPR ) {
         total     := sum( opc, OfflinePlanCell, tempOPC, tempOPC.OfflinePlanRow().ProductionLine() = totalOPR.ProductionLine() and tempOPC.OfflinePlanRow().Type() = "1", [Real]tempOPC.Value() );
-        totalCell := opc.OfflinePlanCell( relnew, Value := [String]total );
-        totalCell.OfflinePlanRow( relset, totalOPR );
+        totalCell := totalOPR.OfflinePlanCell( relnew, Value := [String]total );
+        totalCell.OfflinePlanColumn( relset, opc );
       }
       
       // &鐝
       traverse ( shiftOPRs, Elements, shiftOPR ) {
         shift := select( opc, OfflinePlanCell, tempOPC, tempOPC.OfflinePlanRow().ProductionLine() = shiftOPR.ProductionLine() and tempOPC.OfflinePlanRow().Type() = "1" ); 
         if ( not isnull( shift ) ) {
-          shiftCell := opc.OfflinePlanCell( relnew, Value := shift.Shift() );
-          shiftCell.OfflinePlanRow( relset, shiftOPR );
+          shiftCell := shiftOPR.OfflinePlanCell( relnew, Value := shift.Shift() );
+          shiftCell.OfflinePlanColumn( relset, opc );
         }
       }
       
@@ -113,8 +114,8 @@
         shift := select( opc, OfflinePlanCell, tempOPC, tempOPC.OfflinePlanRow().ProductionLine() = ssdOPR.ProductionLine() and tempOPC.OfflinePlanRow().Type() = "1" ); 
         if ( not isnull( shift ) ) {
           startDate     := guard( minselect( macroPlan, ShiftPattern.ShiftDayTime, tempSDT, tempSDT.ShiftPattern().Name() = shift.Shift(), tempSDT.Sequence() ).StartDateTime().Format( "H:m" ), "" );
-          startDateCell := opc.OfflinePlanCell( relnew, Value := startDate );
-          startDateCell.OfflinePlanRow( relset, ssdOPR );
+          startDateCell := ssdOPR.OfflinePlanCell( relnew, Value := startDate );
+          startDateCell.OfflinePlanColumn( relset, opc );
         }
       }
       
@@ -123,8 +124,8 @@
         shift := select( opc, OfflinePlanCell, tempOPC, tempOPC.OfflinePlanRow().ProductionLine() = sedOPR.ProductionLine() and tempOPC.OfflinePlanRow().Type() = "1" ); 
         if ( not isnull( shift ) ) {
           endDate     := guard( maxselect( macroPlan, ShiftPattern.ShiftDayTime, tempSDT, tempSDT.ShiftPattern().Name() = shift.Shift(), tempSDT.Sequence() ).EndDateTIme().Format( "H:m" ), "" );
-          endDateCell := opc.OfflinePlanCell( relnew, Value := endDate );
-          endDateCell.OfflinePlanRow( relset, sedOPR );
+          endDateCell := sedOPR.OfflinePlanCell( relnew, Value := endDate );
+          endDateCell.OfflinePlanColumn( relset, opc );
         }
       }
     }
@@ -145,12 +146,13 @@
       traverse ( opt, OfflinePlanColumn, opc ) {
         cell := select( opr, OfflinePlanCell, tempOPC, tempOPC.OfflinePlanColumn() = opc );
         if ( isnull( cell ) ) {
-          cell := opc.OfflinePlanCell( relnew, Value := "" );
-          cell.OfflinePlanRow( relset, opr );
+          cell := opr.OfflinePlanCell( relnew, Value := "" );
+          cell.OfflinePlanColumn( relset, opc );
         }
       }
     }
     
+    Transaction::Transaction().Propagate( attribute( OfflinePlanCell, Quantity ) );
     Transaction::Transaction().PropagateAll();
     
     // 璁剧疆鐢熶骇椤哄簭
@@ -161,12 +163,13 @@
       nextColumn     := indexColumn.NextColumn();
       
       while ( not isnull( indexColumn.NextColumn() ) 
-    //          and indexColumn.ColumnDate() <= Date::Construct( 2024, 4, 16 ) // 娴嬭瘯瀹為檯鍦烘櫙鏃跺彲浠ヨ繃婊�
+    //          and indexColumn.ColumnDate() <= Date::Construct( 2020, 4, 1 ) // 娴嬭瘯瀹為檯鍦烘櫙鏃跺彲浠ヨ繃婊�
              ) {
         productionSerialNumber := 1;
         opcs                   := selectsortedset( indexColumn, OfflinePlanCell, tempOPC, tempOPC.FindType( "2", pl ), tempOPC.InventoryWeight() );
         initialSize            := opcs.Size();
-        if ( opcs.Size() > 0 ) {
+        info( "璁″垝寮�濮嬫椂闂达細", macroPlan.StartOfPlanning().Date().Format( "Y-M2-D2" ), "    绱㈠紩鏃堕棿锛�", indexDate.Format( "Y-M2-D2" ), "    涓暟锛�", opcs.Size() );
+        if ( opcs.Size() > 0 ) { 
           // 鍒ゅ畾1
           previousOPC := maxselect( previousColumn, OfflinePlanCell, tempOPC, tempOPC.FindType( "2", pl ), tempOPC.ProductionSerialNumber() );
           if ( isnull( previousOPC ) or indexColumn.ColumnDate() = macroPlan.StartOfPlanning().Date() ) {
diff --git a/_Main/BL/Type_OfflinePlanColumn/Attribute_IsShow.qbl b/_Main/BL/Type_OfflinePlanColumn/Attribute_IsShow.qbl
new file mode 100644
index 0000000..8871340
--- /dev/null
+++ b/_Main/BL/Type_OfflinePlanColumn/Attribute_IsShow.qbl
@@ -0,0 +1,7 @@
+Quintiq file version 2.0
+#parent: #root
+Attribute IsShow
+{
+  #keys: '3[413988.0.1565821671][413988.0.1565821670][413988.0.1565821672]'
+  ValueType: Boolean
+}
diff --git a/_Main/BL/Type_OfflinePlanColumn/DefaultValue_IsShow.qbl b/_Main/BL/Type_OfflinePlanColumn/DefaultValue_IsShow.qbl
new file mode 100644
index 0000000..8bd79cf
--- /dev/null
+++ b/_Main/BL/Type_OfflinePlanColumn/DefaultValue_IsShow.qbl
@@ -0,0 +1,7 @@
+Quintiq file version 2.0
+#parent: #root
+DefaultValue
+{
+  ISOValue: 'true'
+  TargetAttribute: IsShow
+}
diff --git a/_Main/BL/Type_OfflinePlanColumn/Function_CalcColumnIndex.qbl b/_Main/BL/Type_OfflinePlanColumn/Function_CalcColumnIndex.qbl
new file mode 100644
index 0000000..05e1a7d
--- /dev/null
+++ b/_Main/BL/Type_OfflinePlanColumn/Function_CalcColumnIndex.qbl
@@ -0,0 +1,13 @@
+Quintiq file version 2.0
+#parent: #root
+Function CalcColumnIndex
+{
+  TextBody:
+  [*
+    // lihongji Sep-27-2024 (created)
+    
+    value := guard( this.PreviousColumn().ColumnIndex() + 1, 0 )
+    
+    this.ColumnIndex( value );
+  *]
+}
diff --git a/_Main/BL/Type_OfflinePlanImportData/Attribute_Date.qbl b/_Main/BL/Type_OfflinePlanImportData/Attribute_Date.qbl
new file mode 100644
index 0000000..14e1f42
--- /dev/null
+++ b/_Main/BL/Type_OfflinePlanImportData/Attribute_Date.qbl
@@ -0,0 +1,7 @@
+Quintiq file version 2.0
+#parent: #root
+Attribute Date
+{
+  #keys: '3[413988.0.1558681449][413988.0.1558681448][413988.0.1558681450]'
+  ValueType: Date
+}
diff --git a/_Main/BL/Type_OfflinePlanImportData/Attribute_Order.qbl b/_Main/BL/Type_OfflinePlanImportData/Attribute_Order.qbl
new file mode 100644
index 0000000..41491b7
--- /dev/null
+++ b/_Main/BL/Type_OfflinePlanImportData/Attribute_Order.qbl
@@ -0,0 +1,7 @@
+Quintiq file version 2.0
+#parent: #root
+Attribute Order
+{
+  #keys: '3[413988.0.1558681429][413988.0.1558681428][413988.0.1558681430]'
+  ValueType: String
+}
diff --git a/_Main/BL/Type_OfflinePlanImportData/Attribute_ProductID.qbl b/_Main/BL/Type_OfflinePlanImportData/Attribute_ProductID.qbl
new file mode 100644
index 0000000..d98b8b5
--- /dev/null
+++ b/_Main/BL/Type_OfflinePlanImportData/Attribute_ProductID.qbl
@@ -0,0 +1,7 @@
+Quintiq file version 2.0
+#parent: #root
+Attribute ProductID
+{
+  #keys: '3[413988.0.1558681419][413988.0.1558681418][413988.0.1558681420]'
+  ValueType: String
+}
diff --git a/_Main/BL/Type_OfflinePlanImportData/Attribute_Quantity.qbl b/_Main/BL/Type_OfflinePlanImportData/Attribute_Quantity.qbl
new file mode 100644
index 0000000..5a025ff
--- /dev/null
+++ b/_Main/BL/Type_OfflinePlanImportData/Attribute_Quantity.qbl
@@ -0,0 +1,7 @@
+Quintiq file version 2.0
+#parent: #root
+Attribute Quantity
+{
+  #keys: '3[413988.0.1558681439][413988.0.1558681438][413988.0.1558681440]'
+  ValueType: String
+}
diff --git a/_Main/BL/Type_OfflinePlanImportData/StaticMethod_UpdateCell.qbl b/_Main/BL/Type_OfflinePlanImportData/StaticMethod_UpdateCell.qbl
new file mode 100644
index 0000000..c29622a
--- /dev/null
+++ b/_Main/BL/Type_OfflinePlanImportData/StaticMethod_UpdateCell.qbl
@@ -0,0 +1,31 @@
+Quintiq file version 2.0
+#parent: #root
+StaticMethod UpdateCell (
+  GeneralExcelImportAndExportDataTable table,
+  GeneralExcelImportAndExportDataRow row,
+  OfflinePlanTable opt,
+  OfflinePlanRow opr
+)
+{
+  TextBody:
+  [*
+    traverse ( table, GeneralExcelImportAndExportDataColumn, column ) {
+      if ( column.ColumnIndex() = 0 ) {
+        cell := select( column, GeneralExcelImportAndExportDataCell, tempColumn, tempColumn.GeneralExcelImportAndExportDataRow() = row );
+        opc  := select( opt, OfflinePlanColumn, tempOPC, tempOPC.ColumnIndex() = 0 );
+        opcell := opr.OfflinePlanCell( relnew, Value := cell.Value() );
+        opcell.OfflinePlanColumn( relset, opc );
+      } else if ( column.ColumnIndex() = 1 ) {
+        cell := select( column, GeneralExcelImportAndExportDataCell, tempColumn, tempColumn.GeneralExcelImportAndExportDataRow() = row );
+        opc  := select( opt, OfflinePlanColumn, tempOPC, tempOPC.ColumnIndex() = 1 );
+        opcell := opr.OfflinePlanCell( relnew, Value := cell.Value() );
+        opcell.OfflinePlanColumn( relset, opc );
+      } else {
+        cell   := select( column, GeneralExcelImportAndExportDataCell, tempColumn, tempColumn.GeneralExcelImportAndExportDataRow() = row );
+        opc    := select( opt, OfflinePlanColumn, tempOPC, tempOPC.ColumnName() = column.Name() );
+        opcell := opr.OfflinePlanCell( relnew, Value := cell.Value() );
+        opcell.OfflinePlanColumn( relset, opc );
+      }
+    }
+  *]
+}
diff --git a/_Main/BL/Type_OfflinePlanImportData/StaticMethod_Upload.qbl b/_Main/BL/Type_OfflinePlanImportData/StaticMethod_Upload.qbl
new file mode 100644
index 0000000..9060059
--- /dev/null
+++ b/_Main/BL/Type_OfflinePlanImportData/StaticMethod_Upload.qbl
@@ -0,0 +1,66 @@
+Quintiq file version 2.0
+#parent: #root
+StaticMethod Upload (
+  MacroPlan macroPlan,
+  OfflinePlanTable opt,
+  GeneralExcelImportAndExportDataTable table
+)
+{
+  TextBody:
+  [*
+    indexUnitID    := "";
+    indexProductID := "";
+    
+    traverse ( table, GeneralExcelImportAndExportDataRow, row ) {
+      firstColumn  := select( table, GeneralExcelImportAndExportDataColumn, tempC, tempC.ColumnIndex() = 0 );
+      secondColumn := select( table, GeneralExcelImportAndExportDataColumn, tempC, tempC.ColumnIndex() = 1 );
+      
+      firstCell    := select( row, GeneralExcelImportAndExportDataCell, tempC, tempC.GeneralExcelImportAndExportDataColumn() = firstColumn );
+      u            := select( macroPlan, Unit, tempU, tempU.ID() = firstCell.Value() );
+      product      := select( macroPlan, Product_MP, tempPMP, tempPMP.ID() = firstCell.Value() );
+      
+      secondCell    := select( row, GeneralExcelImportAndExportDataCell, tempC, tempC.GeneralExcelImportAndExportDataColumn() = secondColumn );
+      
+      if ( not isnull( u ) and secondCell.Value() = "" ) {
+        indexUnitID := u.ID();
+        opr         := select( opt, OfflinePlanRow, tempOPR, tempOPR.ProductionLine() = indexUnitID and tempOPR.ProductID() = "" and tempOPR.Type() = "0" );
+        opr.OfflinePlanCell( relflush );
+        
+        OfflinePlanImportData::UpdateCell( table, row, opt, opr );
+      } else if ( not isnull( product ) and secondCell.Value() = "Quantity" ) {
+        indexProductID := product.ID();
+        opr            := select( opt, OfflinePlanRow, tempOPR, tempOPR.ProductionLine() = indexUnitID and tempOPR.ProductID() = indexProductID and tempOPR.Type() = "1" );
+        opr.OfflinePlanCell( relflush );
+        
+        OfflinePlanImportData::UpdateCell( table, row, opt, opr );
+      } else if ( isnull( product ) and secondCell.Value() = "Order" ) {
+        opr := select( opt, OfflinePlanRow, tempOPR, tempOPR.ProductionLine() = indexUnitID and tempOPR.ProductID() = indexProductID and tempOPR.Type() = "2" );
+        opr.OfflinePlanCell( relflush );
+        
+        OfflinePlanImportData::UpdateCell( table, row, opt, opr );
+      } else if ( firstCell.Value() = "鍚堣" and secondCell.Value() = "鎬婚噺" ) {
+        opr := select( opt, OfflinePlanRow, tempOPR, tempOPR.ProductionLine() = indexUnitID and tempOPR.ProductID() = "Z" and tempOPR.Type() = "3" );
+        opr.OfflinePlanCell( relflush );
+        
+        OfflinePlanImportData::UpdateCell( table, row, opt, opr );
+      } else if ( firstCell.Value() = "" and secondCell.Value() = "鐝" ) {
+        opr := select( opt, OfflinePlanRow, tempOPR, tempOPR.ProductionLine() = indexUnitID and tempOPR.ProductID() = "Z" and tempOPR.Type() = "4" );
+        opr.OfflinePlanCell( relflush );
+        
+        OfflinePlanImportData::UpdateCell( table, row, opt, opr );
+      } else if ( firstCell.Value() = "" and secondCell.Value() = "鐝寮�濮嬫椂闂�" ) {
+        opr := select( opt, OfflinePlanRow, tempOPR, tempOPR.ProductionLine() = indexUnitID and tempOPR.ProductID() = "Z" and tempOPR.Type() = "5" );
+        opr.OfflinePlanCell( relflush );
+        
+        OfflinePlanImportData::UpdateCell( table, row, opt, opr );
+      } else if ( firstCell.Value() = "" and secondCell.Value() = "鐝缁撴潫鏃堕棿" ) {
+        opr := select( opt, OfflinePlanRow, tempOPR, tempOPR.ProductionLine() = indexUnitID and tempOPR.ProductID() = "Z" and tempOPR.Type() = "6" );
+        opr.OfflinePlanCell( relflush );
+        
+        OfflinePlanImportData::UpdateCell( table, row, opt, opr );
+      } else {
+        error( "瀵煎叆澶辫触锛屾暟鎹紓甯�" );
+      }
+    }
+  *]
+}
diff --git a/_Main/BL/Type_OfflinePlanImportData/_ROOT_Type_OfflinePlanImportData.qbl b/_Main/BL/Type_OfflinePlanImportData/_ROOT_Type_OfflinePlanImportData.qbl
new file mode 100644
index 0000000..ae1bf89
--- /dev/null
+++ b/_Main/BL/Type_OfflinePlanImportData/_ROOT_Type_OfflinePlanImportData.qbl
@@ -0,0 +1,9 @@
+Quintiq file version 2.0
+#root
+#parent: #DomainModel
+Type OfflinePlanImportData
+{
+  #keys: '5[413988.0.1558681402][413988.0.1558681400][0.0.0][413988.0.1558681401][413988.0.1558681403]'
+  BaseType: Object
+  StructuredName: 'OfflinePlanImportDatas'
+}
diff --git a/_Main/BL/Type_OfflinePlanRow/Attribute_Notes.qbl b/_Main/BL/Type_OfflinePlanRow/Attribute_Notes.qbl
index b3d7f68..5630cec 100644
--- a/_Main/BL/Type_OfflinePlanRow/Attribute_Notes.qbl
+++ b/_Main/BL/Type_OfflinePlanRow/Attribute_Notes.qbl
@@ -3,5 +3,6 @@
 Attribute Notes
 {
   #keys: '3[415754.0.180041713][415754.0.180041712][415754.0.180041714]'
+  Description: '4浣嶇爜'
   ValueType: String
 }
diff --git a/_Main/Sys/Repr/Global/OfflinePlanCell.qrp b/_Main/Sys/Repr/Global/OfflinePlanCell.qrp
new file mode 100644
index 0000000..0dade67
--- /dev/null
+++ b/_Main/Sys/Repr/Global/OfflinePlanCell.qrp
@@ -0,0 +1,21 @@
+Quintiq file version 2.0
+#parent: #root
+TypeRepresentation OfflinePlanCell
+{
+  AttributeRepresentation Value
+  {
+    AttributeKey: '[413988.0.1296697079]'
+    Conditional:
+    [
+      DataRepresentation.Conditional
+      {
+        BackgroundColor: '$FF3399'
+        ConditionBody: 'object.IsQuantity()'
+        ConversionBody: ''
+        DefaultBackgroundColor: false
+        InheritConversion: false
+      }
+    ]
+  }
+  RelationRepresentation OfflinePlanColumn { RelationKey: '[413988.0.1296697090]' Visibility: 'Normal' }
+}
diff --git a/_Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Component_mbMainMenu.def b/_Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Component_mbMainMenu.def
index 07043ad..ab7805e 100644
--- a/_Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Component_mbMainMenu.def
+++ b/_Main/UI/MacroPlanner/Component_ApplicationLibMacroPlanner/Component_mbMainMenu.def
@@ -85,6 +85,8 @@
         Component ComponentMenu702 { #keys: '[413988.0.1234424010]' BaseType: 'ComponentMenu' Properties: [ ComponentType: 'frmStandardAnalysis822' Text: 'Interface Dataset' ] }
         Component menuSeparator891 { #keys: '[413988.0.1263894630]' BaseType: 'Menu' Properties: [ Separator: true ] }
         Component MenuWholeShift { #keys: '[413988.0.1263894682]' BaseType: 'Menu' Properties: [ Image: 'FISH_BOWL' Text: '娴嬭瘯鏁寸彮' ] }
+        Component menuSeparator604 { #keys: '[413988.0.1559834087]' BaseType: 'Menu' Properties: [ Separator: true ] }
+        Component ComponentMenu710 { #keys: '[413988.0.1559834106]' BaseType: 'ComponentMenu' Properties: [ ComponentType: 'frmStandardAnalysis627' Text: '' ] }
       ]
       Properties:
       [
@@ -104,10 +106,12 @@
           c: ComponentMenu469
           c: ComponentMenu357
           c: ComponentMenu702
+          c: ComponentMenu710
           c: menuSeparator222
           c: ComponentMenu347
           c: menuSeparator891
           c: MenuWholeShift
+          c: menuSeparator604
         }
       ]
     }
diff --git a/_Main/UI/MacroPlanner/Component_frmStandardAnalysis627/Component_swTop.def b/_Main/UI/MacroPlanner/Component_frmStandardAnalysis627/Component_swTop.def
new file mode 100644
index 0000000..2e97d32
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_frmStandardAnalysis627/Component_swTop.def
@@ -0,0 +1,29 @@
+Quintiq file version 2.0
+Component swTop
+{
+  #keys: '[530.0.3531806]'
+  BaseType: 'swTop'
+  IsDerived: true
+  Children:
+  [
+    Component spTopLeft
+    {
+      #keys: '[530.0.3531807]'
+      BaseType: 'spTopLeft'
+      IsDerived: true
+      Children:
+      [
+        Component Analysis
+        {
+          #keys: '[530.0.3532065]'
+          BaseType: 'Analysis'
+          IsDerived: true
+          Properties:
+          [
+            GlobalInstance: 'RecycleBin'
+          ]
+        }
+      ]
+    }
+  ]
+}
diff --git a/_Main/UI/MacroPlanner/Component_frmStandardAnalysis627/Component_swTopMost.def b/_Main/UI/MacroPlanner/Component_frmStandardAnalysis627/Component_swTopMost.def
new file mode 100644
index 0000000..8a8fcd7
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_frmStandardAnalysis627/Component_swTopMost.def
@@ -0,0 +1,20 @@
+Quintiq file version 2.0
+Component swTopMost
+{
+  #keys: '[530.0.3531801]'
+  BaseType: 'swTopMost'
+  IsDerived: true
+  Children:
+  [
+    Component SplitterPane1
+    {
+      #keys: '[530.0.3531802]'
+      BaseType: 'SplitterPane1'
+      IsDerived: true
+      Children:
+      [
+        #child: swTop
+      ]
+    }
+  ]
+}
diff --git a/_Main/UI/MacroPlanner/Component_frmStandardAnalysis627/_ROOT_Component_frmStandardAnalysis627.def b/_Main/UI/MacroPlanner/Component_frmStandardAnalysis627/_ROOT_Component_frmStandardAnalysis627.def
new file mode 100644
index 0000000..a0e4ead
--- /dev/null
+++ b/_Main/UI/MacroPlanner/Component_frmStandardAnalysis627/_ROOT_Component_frmStandardAnalysis627.def
@@ -0,0 +1,16 @@
+Quintiq file version 2.0
+#root
+#parent: MacroPlanner
+OrphanComponent frmStandardAnalysis627
+{
+  #keys: '[413988.0.1559834123]'
+  BaseType: 'frmStandardAnalysis'
+  Children:
+  [
+    #child: swTopMost
+  ]
+  Properties:
+  [
+    Title: 'RecycleBin'
+  ]
+}
diff --git a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Component_MatrixEditor951.def b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Component_MatrixEditor951.def
index 463493b..8777a1d 100644
--- a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Component_MatrixEditor951.def
+++ b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Component_MatrixEditor951.def
@@ -44,12 +44,10 @@
           BaseType: 'WebDataExtractor'
           Properties:
           [
-            DataType: 'OfflinePlanTable'
-            FilterArguments: 'entities:QLibMacroPlannerWebUI::ApplicationMacroPlanner.DataHolderCheckedEntities'
-            FixedFilter: 'object.Filter( entities )'
-            Source: 'dhOfflinePlanTable'
+            DataType: 'structured[OfflinePlanRow]'
+            Source: 'dhSelectedOfflinePlanRow'
             Taborder: 0
-            Transformation: 'OfflinePlanRow'
+            Transformation: 'Elements'
           ]
         }
       ]
@@ -73,6 +71,7 @@
           Properties:
           [
             DataType: 'OfflinePlanTable'
+            FixedFilter: 'object.IsShow()'
             Source: 'dhOfflinePlanTable'
             Taborder: 0
             Transformation: 'OfflinePlanColumn'
diff --git "a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Component_pContent\043611.def" "b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Component_pContent\043611.def"
index a78013e..859f9c4 100644
--- "a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Component_pContent\043611.def"
+++ "b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Component_pContent\043611.def"
@@ -16,6 +16,33 @@
         Taborder: 1
       ]
     }
+    Component dhSelectedOfflinePlanRow
+    {
+      #keys: '[413988.0.1557550767]'
+      BaseType: 'WebDataHolder'
+      Databinding: 'structured[OfflinePlanRow]*'
+      Children:
+      [
+        Component deSelectedOfflinePlanRow
+        {
+          #keys: '[413988.0.1557550817]'
+          BaseType: 'WebDataExtractor'
+          Properties:
+          [
+            DataType: 'OfflinePlanTable'
+            FilterArguments: 'entities:QLibMacroPlannerWebUI::ApplicationMacroPlanner.DataHolderCheckedEntities'
+            FixedFilter: 'object.Filter( entities )'
+            Source: 'dhOfflinePlanTable'
+            Taborder: 0
+            Transformation: 'OfflinePlanRow'
+          ]
+        }
+      ]
+      Properties:
+      [
+        Taborder: 2
+      ]
+    }
   ]
   Properties:
   [
diff --git a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Component_pHeader.def b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Component_pHeader.def
index a935cd4..dea8989 100644
--- a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Component_pHeader.def
+++ b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Component_pHeader.def
@@ -1,76 +1,17 @@
 Quintiq file version 2.0
 Component pHeader
 {
-  #keys: '[413988.0.1296872680]'
+  #keys: '[413988.0.1568330469]'
   BaseType: 'WebPanel'
   Children:
   [
-    Component bRefresh
-    {
-      #keys: '[413988.0.1296860898]'
-      BaseType: 'WebButton'
-      Properties:
-      [
-        Image: 'REFRESH'
-        Taborder: 0
-      ]
-    }
-    Component bDownload
-    {
-      #keys: '[413988.0.1296875316]'
-      BaseType: 'WebButton'
-      Properties:
-      [
-        Label: 'Download'
-        Taborder: 1
-      ]
-    }
-    Component bDeductionOfReplacementLoss
-    {
-      #keys: '[413988.0.1297911732]'
-      BaseType: 'WebButton'
-      Properties:
-      [
-        Label: 'Deduction of replacement loss'
-        Taborder: 2
-      ]
-    }
-    Component bRestore
-    {
-      #keys: '[413988.0.1297911774]'
-      BaseType: 'WebButton'
-      Properties:
-      [
-        Label: 'Restore'
-        Taborder: 3
-      ]
-    }
-    Component bSaveAsDraft
-    {
-      #keys: '[413988.0.1297973728]'
-      BaseType: 'WebButton'
-      Properties:
-      [
-        Label: 'Save as draft'
-        Taborder: 4
-      ]
-    }
-    Component bConfirm
-    {
-      #keys: '[413988.0.1297973782]'
-      BaseType: 'WebButton'
-      Properties:
-      [
-        Label: 'Confirm'
-        Taborder: 5
-      ]
-    }
+    #child: pHeader1_799
+    #child: pHeader2
   ]
   Properties:
   [
     Border: true
     FixedSize: true
-    Orientation: 'horizontal'
     Taborder: 0
   ]
 }
diff --git "a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Component_pHeader1\043799.def" "b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Component_pHeader1\043799.def"
new file mode 100644
index 0000000..301f988
--- /dev/null
+++ "b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Component_pHeader1\043799.def"
@@ -0,0 +1,85 @@
+Quintiq file version 2.0
+Component pHeader1 id:pHeader1_799
+{
+  #keys: '[413988.0.1568330588]'
+  BaseType: 'WebPanel'
+  Children:
+  [
+    Component bRefresh
+    {
+      #keys: '[413988.0.1568330589]'
+      BaseType: 'WebButton'
+      Properties:
+      [
+        Image: 'REFRESH'
+        Taborder: 0
+      ]
+    }
+    Component bDownload
+    {
+      #keys: '[413988.0.1568330590]'
+      BaseType: 'WebButton'
+      Properties:
+      [
+        Label: 'Download'
+        Taborder: 1
+      ]
+    }
+    Component bDeductionOfReplacementLoss
+    {
+      #keys: '[413988.0.1568330591]'
+      BaseType: 'WebButton'
+      Properties:
+      [
+        Label: 'Deduction of replacement loss'
+        Taborder: 3
+      ]
+    }
+    Component bRestore
+    {
+      #keys: '[413988.0.1568330592]'
+      BaseType: 'WebButton'
+      Properties:
+      [
+        Label: 'Restore'
+        Taborder: 4
+      ]
+    }
+    Component bSaveAsDraft
+    {
+      #keys: '[413988.0.1568330593]'
+      BaseType: 'WebButton'
+      Properties:
+      [
+        Label: 'Save as draft'
+        Taborder: 5
+      ]
+    }
+    Component bConfirm
+    {
+      #keys: '[413988.0.1568330594]'
+      BaseType: 'WebButton'
+      Properties:
+      [
+        Label: 'Confirm'
+        Taborder: 6
+      ]
+    }
+    Component bImport
+    {
+      #keys: '[413988.0.1568330595]'
+      BaseType: 'WebButton'
+      Properties:
+      [
+        Label: 'Import'
+        Taborder: 2
+      ]
+    }
+  ]
+  Properties:
+  [
+    FixedSize: true
+    Orientation: 'horizontal'
+    Taborder: 0
+  ]
+}
diff --git a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Component_pHeader2.def b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Component_pHeader2.def
new file mode 100644
index 0000000..a206e82
--- /dev/null
+++ b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Component_pHeader2.def
@@ -0,0 +1,25 @@
+Quintiq file version 2.0
+Component pHeader2
+{
+  #keys: '[413988.0.1568330735]'
+  BaseType: 'WebPanel'
+  Children:
+  [
+    Component sDateFilter
+    {
+      #keys: '[413988.0.1567271085]'
+      BaseType: 'WebSlider'
+      Properties:
+      [
+        NumberOfColumns: 100
+        Taborder: 0
+      ]
+    }
+  ]
+  Properties:
+  [
+    FixedSize: true
+    Orientation: 'horizontal'
+    Taborder: 1
+  ]
+}
diff --git a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader_bConfirm_OnClick.def b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bConfirm_OnClick.def
similarity index 75%
rename from _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader_bConfirm_OnClick.def
rename to _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bConfirm_OnClick.def
index ef72979..c878839 100644
--- a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader_bConfirm_OnClick.def
+++ b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bConfirm_OnClick.def
@@ -1,8 +1,8 @@
 Quintiq file version 2.0
-#parent: pHeader/bConfirm
-Response OnClick () id:Response_pHeader_bConfirm_OnClick
+#parent: pHeader1_799/bConfirm
+Response OnClick () id:Response_pHeader1_799_bConfirm_OnClick
 {
-  #keys: '[413988.0.1297974240]'
+  #keys: '[413988.0.1568330582]'
   CanBindMultiple: false
   DefinitionID: 'Responsedef_WebButton_OnClick'
   Precondition:
diff --git a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader_bDeductionOfReplacementLoss_OnClick.def b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bDeductionOfReplacementLoss_OnClick.def
similarity index 76%
rename from _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader_bDeductionOfReplacementLoss_OnClick.def
rename to _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bDeductionOfReplacementLoss_OnClick.def
index 16a2713..181e371 100644
--- a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader_bDeductionOfReplacementLoss_OnClick.def
+++ b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bDeductionOfReplacementLoss_OnClick.def
@@ -1,8 +1,8 @@
 Quintiq file version 2.0
-#parent: pHeader/bDeductionOfReplacementLoss
-Response OnClick () id:Response_pHeader_bDeductionOfReplacementLoss_OnClick
+#parent: pHeader1_799/bDeductionOfReplacementLoss
+Response OnClick () id:Response_pHeader1_799_bDeductionOfReplacementLoss_OnClick
 {
-  #keys: '[413988.0.1297973984]'
+  #keys: '[413988.0.1568330585]'
   CanBindMultiple: false
   DefinitionID: 'Responsedef_WebButton_OnClick'
   Precondition:
diff --git a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bDownload_OnClick.def b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bDownload_OnClick.def
new file mode 100644
index 0000000..5558821
--- /dev/null
+++ b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bDownload_OnClick.def
@@ -0,0 +1,22 @@
+Quintiq file version 2.0
+#parent: pHeader1_799/bDownload
+Response OnClick () id:Response_pHeader1_799_bDownload_OnClick
+{
+  #keys: '[413988.0.1568330586]'
+  CanBindMultiple: false
+  DefinitionID: 'Responsedef_WebButton_OnClick'
+  Precondition:
+  [*
+    return not isnull( MacroPlan );
+  *]
+  QuillAction
+  {
+    Body:
+    [*
+      binaryValue := OfflinePlanCell::Download( MacroPlan, dhSelectedOfflinePlanRow.Data() );
+      
+      Application.Download( "Offline plan.xlsx", binaryValue.AsBinaryData() );
+    *]
+    GroupServerCalls: false
+  }
+}
diff --git a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bImport_OnClick.def b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bImport_OnClick.def
new file mode 100644
index 0000000..08d2e2d
--- /dev/null
+++ b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bImport_OnClick.def
@@ -0,0 +1,45 @@
+Quintiq file version 2.0
+#parent: pHeader1_799/bImport
+Response OnClick () id:Response_pHeader1_799_bImport_OnClick
+{
+  #keys: '[413988.0.1568330581]'
+  CanBindMultiple: false
+  DefinitionID: 'Responsedef_WebButton_OnClick'
+  Precondition:
+  [*
+    return not isnull( MacroPlan );
+  *]
+  QuillAction
+  {
+    Body:
+    [*
+      try {
+        uploadJsonString := Application.GetFile();
+        if ( uploadJsonString <> "" ) {
+          uploadJson := JSON::Parse( uploadJsonString );
+          Archive::VerifyTheFileName( uploadJson );
+                
+          fileName := uploadJson.Get( "name" ).GetString();
+          base64String := uploadJson.Get( "data" ).GetString();
+              
+          webFileBinaryData := BinaryData::FromBase64EncodedString( base64String ).AsBinaryValue();
+          
+          generalExcelImportAndExportDataSource := GeneralExcelImportAndExportDataSource::Upload( RecycleBin, webFileBinaryData, fileName );
+          generalExcelImportAndExportDataSource.ReadStructure();
+          
+          selection := select( generalExcelImportAndExportDataSource, GeneralExcelImportAndExportDataTable, tempGEIAEDT, tempGEIAEDT.Name() = "Sheet1" );
+          
+          OfflinePlanImportData::Upload( MacroPlan, dhOfflinePlanTable.Data(), selection );
+          
+          // 鍚庣画鍒犻櫎
+      //    generalExcelImportAndExportDataSource.Delete();
+          
+          WebMessageBox::Success( Translations::A_VWED_Success() );
+        }
+      } onerror {
+        WebMessageBox::Error( e.GeneralInformation() );
+      }
+    *]
+    GroupServerCalls: false
+  }
+}
diff --git a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader_bRefresh_OnClick.def b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bRefresh_OnClick.def
similarity index 79%
rename from _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader_bRefresh_OnClick.def
rename to _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bRefresh_OnClick.def
index 94d48f9..69d79e7 100644
--- a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader_bRefresh_OnClick.def
+++ b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bRefresh_OnClick.def
@@ -1,8 +1,8 @@
 Quintiq file version 2.0
-#parent: pHeader/bRefresh
-Response OnClick () id:Response_pHeader_bRefresh_OnClick
+#parent: pHeader1_799/bRefresh
+Response OnClick () id:Response_pHeader1_799_bRefresh_OnClick
 {
-  #keys: '[413988.0.1297973814]'
+  #keys: '[413988.0.1568330587]'
   CanBindMultiple: false
   DefinitionID: 'Responsedef_WebButton_OnClick'
   Precondition:
diff --git a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader_bRestore_OnClick.def b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bRestore_OnClick.def
similarity index 82%
rename from _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader_bRestore_OnClick.def
rename to _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bRestore_OnClick.def
index 14e4993..eb75c8b 100644
--- a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader_bRestore_OnClick.def
+++ b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bRestore_OnClick.def
@@ -1,8 +1,8 @@
 Quintiq file version 2.0
-#parent: pHeader/bRestore
-Response OnClick () id:Response_pHeader_bRestore_OnClick
+#parent: pHeader1_799/bRestore
+Response OnClick () id:Response_pHeader1_799_bRestore_OnClick
 {
-  #keys: '[413988.0.1297974069]'
+  #keys: '[413988.0.1568330584]'
   CanBindMultiple: false
   DefinitionID: 'Responsedef_WebButton_OnClick'
   Precondition:
diff --git a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader_bSaveAsDraft_OnClick.def b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bSaveAsDraft_OnClick.def
similarity index 76%
rename from _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader_bSaveAsDraft_OnClick.def
rename to _Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bSaveAsDraft_OnClick.def
index e94ded1..d07d889 100644
--- a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader_bSaveAsDraft_OnClick.def
+++ b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader1_799_bSaveAsDraft_OnClick.def
@@ -1,8 +1,8 @@
 Quintiq file version 2.0
-#parent: pHeader/bSaveAsDraft
-Response OnClick () id:Response_pHeader_bSaveAsDraft_OnClick
+#parent: pHeader1_799/bSaveAsDraft
+Response OnClick () id:Response_pHeader1_799_bSaveAsDraft_OnClick
 {
-  #keys: '[413988.0.1297974155]'
+  #keys: '[413988.0.1568330583]'
   CanBindMultiple: false
   DefinitionID: 'Responsedef_WebButton_OnClick'
   Precondition:
diff --git a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader2_sDateFilter_OnUserChanged.def b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader2_sDateFilter_OnUserChanged.def
new file mode 100644
index 0000000..d95c376
--- /dev/null
+++ b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader2_sDateFilter_OnUserChanged.def
@@ -0,0 +1,26 @@
+Quintiq file version 2.0
+#parent: pHeader2/sDateFilter
+Response OnUserChanged () id:Response_pHeader2_sDateFilter_OnUserChanged
+{
+  #keys: '[413988.0.1568579788]'
+  CanBindMultiple: false
+  DefinitionID: 'Responsedef_WebSlider_OnUserChanged'
+  Precondition:
+  [*
+    return not isnull( MacroPlan );
+  *]
+  QuillAction
+  {
+    Body:
+    [*
+      traverse ( dhOfflinePlanTable.Data(), OfflinePlanColumn, opc ) {
+       opc.IsShow( true ); 
+      
+        if ( opc.ColumnIndex() > 1 and opc.ColumnIndex() < this.EndReal() ) {
+          opc.IsShow( false );
+        }
+      }
+    *]
+    GroupServerCalls: false
+  }
+}
diff --git a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader_bDownload_OnClick.def b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader_bDownload_OnClick.def
deleted file mode 100644
index 7e12122..0000000
--- a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/Response_pHeader_bDownload_OnClick.def
+++ /dev/null
@@ -1,22 +0,0 @@
-Quintiq file version 2.0
-#parent: pHeader/bDownload
-Response OnClick () id:Response_pHeader_bDownload_OnClick
-{
-  #keys: '[413988.0.1297973899]'
-  CanBindMultiple: false
-  DefinitionID: 'Responsedef_WebButton_OnClick'
-  Precondition:
-  [*
-    return not isnull( MacroPlan );
-  *]
-  QuillAction
-  {
-    Body:
-    [*
-      binaryValue := OfflinePlanCell::Download( MacroPlan );
-      
-      Application.Download( "Offline plan.xlsx", binaryValue.AsBinaryData() );
-    *]
-    GroupServerCalls: false
-  }
-}
diff --git a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/_ROOT_Component_FormOfflinePlan.def b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/_ROOT_Component_FormOfflinePlan.def
index be8fe4d..8d1b9fc 100644
--- a/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/_ROOT_Component_FormOfflinePlan.def
+++ b/_Main/UI/MacroPlannerWebApp/Component_FormOfflinePlan/_ROOT_Component_FormOfflinePlan.def
@@ -7,8 +7,8 @@
   BaseType: 'WebForm'
   Children:
   [
-    #child: pHeader
     #child: pContent
+    #child: pHeader
   ]
   Properties:
   [

--
Gitblit v1.9.3