From be9f3270a50b9f5318beff37bd4d70fa5632657a Mon Sep 17 00:00:00 2001
From: yypsybs <yypsybs@foxmail.com>
Date: 星期五, 08 九月 2023 17:31:05 +0800
Subject: [PATCH] 4.11.物料属性标签设定&物料计划策略

---
 _Main/UI/MacroPlannerWebApp/Component_DialogEdit/Method_OnOK.def                                                                                   |   16 +
 _Main/BL/Type_MatAttrSettingAndPlanningStrategy/Attribute_FlagGeneric.qbl                                                                          |    6 
 _Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Method_parseTable.qbl                                                                       |    9 
 _Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_DeleteIfExistByMatCode#526.qbl                                                        |    6 
 _Main/BL/InfoMessages.qbl                                                                                                                          |    5 
 _Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/_ROOT_Type_MatAttrSettingAndPlanStrategyDetail.qbl                                               |   10 
 _Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_CreateIfNotExist.qbl                                                                  |   31 +
 _Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategyDetail/Component_ListMatAttrSettingAndPlanStrategyDetail#21.def             |  106 ++++++
 _Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategyDetail/Component_listContextMenuMatAttrSettingAndPlanStrategyDetail#1.def   |   10 
 _Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Attribute_ProductDesc.qbl                                                                        |    8 
 _Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/_ROOT_Component_FormMatAttrSettingAndPlanStrategy.def                      |   39 ++
 _Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategyDetail/_ROOT_Component_FormMatAttrSettingAndPlanStrategyDetail.def          |   17 +
 _Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Component_listActionBarPageMatAttrSettingAndPlanStrategy.def               |   10 
 _Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Attribute_base64Str.qbl                                                                     |    4 
 _Main/UI/MacroPlannerWebApp/Component_DialogEdit/_ROOT_Component_DialogEditMatAttrSettingAndPlanStrategy.def                                       |   31 +
 _Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Attribute_ProductCode.qbl                                                                        |    8 
 _Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_update.qbl                                                                            |   51 ++-
 _Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Attribute_StandardLT.qbl                                                                         |    7 
 _Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Component_ListMatAttrSettingAndPlanStrategy.def                            |  105 ++++++
 _Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Method_saveData.qbl                                                                         |    4 
 _Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Attribute_userName.qbl                                                                      |    7 
 _Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Attribute_isXlsx.qbl                                                                        |    2 
 _Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/StaticMethod_upload.qbl                                                                     |   12 
 _Main/UI/MacroPlannerWebApp/Component_DialogEdit/Response_pnlActions_btnOk_OnClick.def                                                             |   15 
 _Main/BL/Type_MatAttrSettingAndPlanStrategyDataTable/StaticMethod_export.qbl                                                                       |   20 
 _Main/BL/Type_MatAttrSettingAndPlanningStrategy/Function_CalcProductCount.qbl                                                                      |   13 
 _Main/BL/Type_MatAttrSettingAndPlanStrategyDataTable/StaticMethod_expectedHeaders.qbl                                                              |    2 
 _Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Method_createTable.qbl                                                                      |    2 
 _Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Response_ButtonMatAttrSettingAndPlanStrategyImport_OnClick.def             |   32 ++
 _Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategyDetail/Component_listActionBarPageMatAttrSettingAndPlanStrategyDetail#1.def |   10 
 _Main/BL/Type_MatAttrSettingAndPlanningStrategy/Attribute_FlagLongTerm.qbl                                                                         |    6 
 _Main/BL/Type_MatAttrSettingAndPlanningStrategy/Function_CalcPlanningStrategyAuto.qbl                                                              |   23 +
 _Main/UI/MacroPlannerWebApp/Component_DialogEdit/Component_pnlActions.def                                                                          |   40 ++
 _Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Response_ListMatAttrSettingAndPlanStrategy_MenuEdit_OnClick.def            |   20 +
 _Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Component_listContextMenuMatAttrSettingAndPlanStrategy.def                 |   27 +
 _Main/BL/Type_MatAttrSettingAndPlanningStrategy/Function_CalcMinProdDeliverLT.qbl                                                                  |   17 +
 _Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_getExistByMatCode.qbl                                                                 |    2 
 _Main/BL/Type_MatAttrSettingAndPlanningStrategy/Attribute_PlanningStrategyAuto.qbl                                                                 |    6 
 _Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Response_ButtonMatAttrSettingAndPlanStrategyExport_OnClick.def             |   18 +
 _Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/StaticMethod_CreateIfNotExist.qbl                                                                |   22 +
 _Main/BL/Type_GlobalDTOTable/Method_InitTestData.qbl                                                                                               |   17 +
 _Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Response_OnCreated.def                                                     |   17 +
 _Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Attribute_MatCode.qbl                                                                            |    8 
 _Main/BL/Type_MatAttrSettingAndPlanStrategyDataTable/StaticMethod_exportFields.qbl                                                                 |    2 
 _Main/UI/MacroPlannerWebApp/Component_DialogEdit/Component_pnlContent.def                                                                          |   27 +
 _Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_delete.qbl                                                                            |    2 
 _Main/UI/MacroPlannerWebApp/Component_DialogEdit/Response_pnlActions_btnCancel_OnClick.def                                                         |   15 
 _Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Attribute_fileName.qbl                                                                      |    2 
 _Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_deleteIfExistByMatCode.qbl                                                            |    2 
 _Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Attribute_Comment.qbl                                                                            |    8 
 _Main/BL/Relations/Relation_MatAttrSettingAndPlanStrategyDetail_MatAttrSettingAndPlanStrategy_M.qbl                                                |   23 +
 _Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Function_CalcMatCode.qbl                                                                         |   13 
 _Main/BL/Type_MatAttrSettingAndPlanStrategyDataTable/StaticMethod_doVerify.qbl                                                                     |    4 
 _Main/UI/MacroPlannerWebApp/Component_DialogEdit/Method_Edit.def                                                                                   |   17 +
 54 files changed, 879 insertions(+), 57 deletions(-)

diff --git a/_Main/BL/InfoMessages.qbl b/_Main/BL/InfoMessages.qbl
new file mode 100644
index 0000000..d3fc0df
--- /dev/null
+++ b/_Main/BL/InfoMessages.qbl
@@ -0,0 +1,5 @@
+Quintiq file version 2.0
+#parent: #root
+InfoMessages id:#InfoMessages #extension
+{
+}
diff --git a/_Main/BL/Relations/Relation_MatAttrSettingAndPlanStrategyDetail_MatAttrSettingAndPlanStrategy_M.qbl b/_Main/BL/Relations/Relation_MatAttrSettingAndPlanStrategyDetail_MatAttrSettingAndPlanStrategy_M.qbl
new file mode 100644
index 0000000..b1fc594
--- /dev/null
+++ b/_Main/BL/Relations/Relation_MatAttrSettingAndPlanStrategyDetail_MatAttrSettingAndPlanStrategy_M.qbl
@@ -0,0 +1,23 @@
+Quintiq file version 2.0
+#parent: #root
+Relation MatAttrSettingAndPlanStrategyDetail_MatAttrSettingAndPlanStrategy_MatAttrSettingAndPlanStrategy_MatAttrSettingAndPlanStrategyDetail
+{
+  #keys: '1[414384.0.766881387]'
+  DefaultRelationStrategy
+  {
+  }
+  RelationSide.LeftSide MatAttrSettingAndPlanStrategy
+  {
+    #keys: '3[414384.0.766881389][414384.0.766881388][414384.0.766881390]'
+    Cardinality: '0to1'
+    ObjectDefinition: MatAttrSettingAndPlanStrategyDetail
+    OwningSide: 'Reference'
+  }
+  RelationSide.RightSide MatAttrSettingAndPlanStrategyDetail
+  {
+    #keys: '3[414384.0.766881392][414384.0.766881391][414384.0.766881393]'
+    Cardinality: '1toN'
+    ObjectDefinition: MatAttrSettingAndPlanStrategy
+    OwningSide: 'Owned'
+  }
+}
diff --git a/_Main/BL/Type_GlobalDTOTable/Method_InitTestData.qbl b/_Main/BL/Type_GlobalDTOTable/Method_InitTestData.qbl
new file mode 100644
index 0000000..0ad0d09
--- /dev/null
+++ b/_Main/BL/Type_GlobalDTOTable/Method_InitTestData.qbl
@@ -0,0 +1,17 @@
+Quintiq file version 2.0
+#parent: #root
+Method InitTestData
+{
+  TextBody:
+  [*
+    // yypsybs Sep-8-2023 (created)
+    mat1 := MatAttrSettingAndPlanStrategy::CreateIfNotExist( this, "MAT_1", "MAT_1", "TYPE_1", 233.0, "閫氱敤", "闀垮懆鏈�" );
+    MatAttrSettingAndPlanStrategyDetail::CreateIfNotExist( mat1, "PROD_1", 666.0, "PROD_1_DESC" );
+    MatAttrSettingAndPlanStrategyDetail::CreateIfNotExist( mat1, "PROD_2", 777.0, "PROD_2_DESC" );
+    mat2 := MatAttrSettingAndPlanStrategy::CreateIfNotExist( this, "MAT_2", "MAT_2", "TYPE_2", 233.0, "涓撶敤", "闀垮懆鏈�" );
+    MatAttrSettingAndPlanStrategyDetail::CreateIfNotExist( mat2, "PROD_1", 1666.0, "PROD_1_DESC" );
+    MatAttrSettingAndPlanStrategyDetail::CreateIfNotExist( mat2, "PROD_2", 1777.0, "PROD_2_DESC" );
+    MatAttrSettingAndPlanStrategy::CreateIfNotExist( this, "MAT_3", "MAT_3", "TYPE_1", 233.0, "閫氱敤", "鐭懆鏈�" );
+    MatAttrSettingAndPlanStrategy::CreateIfNotExist( this, "MAT_4", "MAT_4", "TYPE_2", 233.0, "涓撶敤", "鐭懆鏈�" );
+  *]
+}
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanStrategyDataTable/StaticMethod_doVerify.qbl b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDataTable/StaticMethod_doVerify.qbl
index adcdcf6..3a85db8 100644
--- a/_Main/BL/Type_MatAttrSettingAndPlanStrategyDataTable/StaticMethod_doVerify.qbl
+++ b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDataTable/StaticMethod_doVerify.qbl
@@ -1,6 +1,6 @@
 Quintiq file version 2.0
 #parent: #root
-StaticMethod doVerify (
+StaticMethod DoVerify (
   MatAttrSettingAndPlanStrategyDataTable toVerify
 )
 {
@@ -19,7 +19,7 @@
     //}
     // for test end
     
-    expectedHeaders := MatAttrSettingAndPlanStrategyDataTable::expectedHeaders();
+    expectedHeaders := MatAttrSettingAndPlanStrategyDataTable::ExpectedHeaders();
     traverse( columns, Elements, column ) {
       columnActualName := column.name();
       if( column.columnIndex() > expectedHeaders.Size() ) {
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanStrategyDataTable/StaticMethod_expectedHeaders.qbl b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDataTable/StaticMethod_expectedHeaders.qbl
index 156988a..477f603 100644
--- a/_Main/BL/Type_MatAttrSettingAndPlanStrategyDataTable/StaticMethod_expectedHeaders.qbl
+++ b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDataTable/StaticMethod_expectedHeaders.qbl
@@ -1,6 +1,6 @@
 Quintiq file version 2.0
 #parent: #root
-StaticMethod expectedHeaders () as owning Strings
+StaticMethod ExpectedHeaders () as owning Strings
 {
   TextBody:
   [*
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanStrategyDataTable/StaticMethod_export.qbl b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDataTable/StaticMethod_export.qbl
index 4165312..35be39b 100644
--- a/_Main/BL/Type_MatAttrSettingAndPlanStrategyDataTable/StaticMethod_export.qbl
+++ b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDataTable/StaticMethod_export.qbl
@@ -1,19 +1,19 @@
 Quintiq file version 2.0
 #parent: #root
-StaticMethod export (
+StaticMethod Export (
   GlobalOTDTable parent
-) as BinaryValue
+) as String
 {
   TextBody:
   [*
     // yypsybs Jul-1-2023 (created)
     xmlTemplate := '<?xml version="1.0" encoding="UTF-16"?>
     <table>
-      <name>MatAttrSettingAndPlanningStrategy</name>
+      <name>MatAttrSettingAndPlanStrategy</name>
     ';
     //---------------------------------------------------------------------------------------------
-    exportFields := MatAttrSettingAndPlanStrategyDataTable::exportFields();
-    exportHeaders := MatAttrSettingAndPlanStrategyDataTable::expectedHeaders();
+    exportFields := MatAttrSettingAndPlanStrategyDataTable::ExportFields();
+    exportHeaders := MatAttrSettingAndPlanStrategyDataTable::ExpectedHeaders();
     if( exportFields.Size() <> exportHeaders.Size() ) {
       error( "fields and headers not match" );  
     }
@@ -22,7 +22,7 @@
       columnStr := "<column><name>" + header + "</name><type>String</type>";
       traverse( parent, MatAttrSettingAndPlanStrategy, oldRecord ) {
         fieldName := exportFields.Element( i );
-        field := Reflection::FindAttribute( "MatAttrSettingAndPlanningStrategy", fieldName);
+        field := Reflection::FindAttribute( "MatAttrSettingAndPlanStrategy", fieldName);
         if( not isnull( field ) ) {
           fieldValue := "";
           if( fieldValue = "" ) {
@@ -47,7 +47,7 @@
           
           columnStr := columnStr + cellStr;
         } else {
-          error( "no field " + fieldName + " in type MatAttrSettingAndPlanningStrategy");
+          error( "no field " + fieldName + " in type MatAttrSettingAndPlanStrategy");
         }
       }
       columnStr := columnStr + "</column>";
@@ -56,10 +56,10 @@
     //---------------------------------------------------------------------------------------------
     xmlTemplate := xmlTemplate + "</table>";
     tableHandle := TableHandle::ImportXML( BinaryValue::Construct( xmlTemplate ) );
-    XLS::SaveTable( tableHandle, OS::TempPath() + "MatAttrSettingAndPlanningStrategy.xlsx" );
+    XLS::SaveTable( tableHandle, OS::TempPath() + "MatAttrSettingAndPlanStrategy.xlsx" );
     file := OSFile::Construct();
-    file.Open( OS::TempPath() + "MatAttrSettingAndPlanningStrategy.xlsx", "Read", true );
+    file.Open( OS::TempPath() + "MatAttrSettingAndPlanStrategy.xlsx", "Read", true );
     data := file.ReadBinary()
-    return data;
+    return data.AsBase64EncodedString();
   *]
 }
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanStrategyDataTable/StaticMethod_exportFields.qbl b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDataTable/StaticMethod_exportFields.qbl
index 6559348..d45757b 100644
--- a/_Main/BL/Type_MatAttrSettingAndPlanStrategyDataTable/StaticMethod_exportFields.qbl
+++ b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDataTable/StaticMethod_exportFields.qbl
@@ -1,6 +1,6 @@
 Quintiq file version 2.0
 #parent: #root
-StaticMethod exportFields () as owning Strings
+StaticMethod ExportFields () as owning Strings
 {
   TextBody:
   [*
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Attribute_Comment.qbl b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Attribute_Comment.qbl
new file mode 100644
index 0000000..29e121e
--- /dev/null
+++ b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Attribute_Comment.qbl
@@ -0,0 +1,8 @@
+Quintiq file version 2.0
+#parent: #root
+Attribute Comment
+{
+  #keys: '3[414384.0.766881447][414384.0.766881446][414384.0.766881448]'
+  Description: '澶囨敞'
+  ValueType: String
+}
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Attribute_MatCode.qbl b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Attribute_MatCode.qbl
new file mode 100644
index 0000000..7ee0a19
--- /dev/null
+++ b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Attribute_MatCode.qbl
@@ -0,0 +1,8 @@
+Quintiq file version 2.0
+#parent: #root
+Attribute MatCode
+{
+  #keys: '3[414384.0.766881404][414384.0.766881403][414384.0.766881405]'
+  Description: '鐗╂枡缂栫爜'
+  ValueType: String
+}
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Attribute_ProductCode.qbl b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Attribute_ProductCode.qbl
new file mode 100644
index 0000000..d55171e
--- /dev/null
+++ b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Attribute_ProductCode.qbl
@@ -0,0 +1,8 @@
+Quintiq file version 2.0
+#parent: #root
+Attribute ProductCode
+{
+  #keys: '3[414384.0.766881414][414384.0.766881413][414384.0.766881415]'
+  Description: '鎴愬搧缂栫爜'
+  ValueType: String
+}
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Attribute_ProductDesc.qbl b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Attribute_ProductDesc.qbl
new file mode 100644
index 0000000..0993c0f
--- /dev/null
+++ b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Attribute_ProductDesc.qbl
@@ -0,0 +1,8 @@
+Quintiq file version 2.0
+#parent: #root
+Attribute ProductDesc
+{
+  #keys: '3[414384.0.766881437][414384.0.766881436][414384.0.766881438]'
+  Description: '鎴愬搧鎻忚堪'
+  ValueType: String
+}
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Attribute_StandardLT.qbl b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Attribute_StandardLT.qbl
new file mode 100644
index 0000000..5fce24d
--- /dev/null
+++ b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Attribute_StandardLT.qbl
@@ -0,0 +1,7 @@
+Quintiq file version 2.0
+#parent: #root
+Attribute StandardLT
+{
+  #keys: '3[414384.0.766881424][414384.0.766881423][414384.0.766881425]'
+  ValueType: Real
+}
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Function_CalcMatCode.qbl b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Function_CalcMatCode.qbl
new file mode 100644
index 0000000..0b3b836
--- /dev/null
+++ b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/Function_CalcMatCode.qbl
@@ -0,0 +1,13 @@
+Quintiq file version 2.0
+#parent: #root
+Function CalcMatCode
+{
+  TextBody:
+  [*
+    // yypsybs Sep-8-2023 (created)
+    
+    value := this.MatAttrSettingAndPlanStrategy().MatCode();
+    
+    this.MatCode( value );
+  *]
+}
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/StaticMethod_CreateIfNotExist.qbl b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/StaticMethod_CreateIfNotExist.qbl
new file mode 100644
index 0000000..44625cb
--- /dev/null
+++ b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/StaticMethod_CreateIfNotExist.qbl
@@ -0,0 +1,22 @@
+Quintiq file version 2.0
+#parent: #root
+StaticMethod CreateIfNotExist (
+  MatAttrSettingAndPlanStrategy parent,
+  String productCode,
+  Real standardLT,
+  String productDesc
+) as MatAttrSettingAndPlanStrategyDetail
+{
+  TextBody:
+  [*
+    // yypsybs Sep-8-2023 (created)
+    value := select( parent, MatAttrSettingAndPlanStrategyDetail, item, item.ProductCode() = productCode );
+    if( isnull( value ) ) {
+      value := parent.MatAttrSettingAndPlanStrategyDetail( relnew,
+                                                           ProductCode := productCode, 
+                                                           StandardLT := standardLT, 
+                                                           ProductDesc := productDesc );
+    }
+    return value;
+  *]
+}
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/_ROOT_Type_MatAttrSettingAndPlanStrategyDetail.qbl b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/_ROOT_Type_MatAttrSettingAndPlanStrategyDetail.qbl
new file mode 100644
index 0000000..ea00f4b
--- /dev/null
+++ b/_Main/BL/Type_MatAttrSettingAndPlanStrategyDetail/_ROOT_Type_MatAttrSettingAndPlanStrategyDetail.qbl
@@ -0,0 +1,10 @@
+Quintiq file version 2.0
+#root
+#parent: #DomainModel
+Type MatAttrSettingAndPlanStrategyDetail
+{
+  #keys: '5[414384.0.766881384][414384.0.766881382][0.0.0][414384.0.766881383][414384.0.766881385]'
+  BaseType: Object
+  Description: '鐗╂枡灞炴�ф爣绛捐瀹�&鐗╂枡璁″垝绛栫暐鏄庣粏'
+  StructuredName: 'MatAttrSettingAndPlanStrategyDetails'
+}
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Attribute_bytes.qbl b/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Attribute_base64Str.qbl
similarity index 73%
rename from _Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Attribute_bytes.qbl
rename to _Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Attribute_base64Str.qbl
index d57a443..c4af056 100644
--- a/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Attribute_bytes.qbl
+++ b/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Attribute_base64Str.qbl
@@ -1,7 +1,7 @@
 Quintiq file version 2.0
 #parent: #root
-Attribute bytes
+Attribute Base64Str
 {
   #keys: '3[414384.0.763764696][414384.0.763764695][414384.0.763764697]'
-  ValueType: BinaryValue
+  ValueType: String
 }
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Attribute_fileName.qbl b/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Attribute_fileName.qbl
index fb1168e..f02d671 100644
--- a/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Attribute_fileName.qbl
+++ b/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Attribute_fileName.qbl
@@ -1,6 +1,6 @@
 Quintiq file version 2.0
 #parent: #root
-Attribute fileName
+Attribute FileName
 {
   #keys: '3[414384.0.763764699][414384.0.763764698][414384.0.763764700]'
   ValueType: String
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Attribute_isXlsx.qbl b/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Attribute_isXlsx.qbl
index 59af587..e39af74 100644
--- a/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Attribute_isXlsx.qbl
+++ b/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Attribute_isXlsx.qbl
@@ -1,6 +1,6 @@
 Quintiq file version 2.0
 #parent: #root
-Attribute isXlsx
+Attribute IsXlsx
 {
   #keys: '3[414384.0.763764702][414384.0.763764701][414384.0.763764703]'
   ValueType: Boolean
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Attribute_userName.qbl b/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Attribute_userName.qbl
new file mode 100644
index 0000000..3ad1938
--- /dev/null
+++ b/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Attribute_userName.qbl
@@ -0,0 +1,7 @@
+Quintiq file version 2.0
+#parent: #root
+Attribute UserName
+{
+  #keys: '3[414384.0.775080571][414384.0.775080570][414384.0.775080572]'
+  ValueType: String
+}
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Method_createTable.qbl b/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Method_createTable.qbl
index 3ed388c..1729ebf 100644
--- a/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Method_createTable.qbl
+++ b/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Method_createTable.qbl
@@ -1,6 +1,6 @@
 Quintiq file version 2.0
 #parent: #root
-Method createTable (
+Method CreateTable (
   String sheetName
 ) as MatAttrSettingAndPlanStrategyDataTable
 {
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Method_parseTable.qbl b/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Method_parseTable.qbl
index e69abc2..b970d61 100644
--- a/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Method_parseTable.qbl
+++ b/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Method_parseTable.qbl
@@ -1,15 +1,16 @@
 Quintiq file version 2.0
 #parent: #root
-Method parseTable
+Method ParseTable
 {
   TextBody:
   [*
     // yypsybs Jul-1-2023 (created)
-    tableGroupHandle := TableGroupHandle::Create( this.fileName() );
-    tableGroupHandle := XLS::LoadTableGroupFromBinaryData( this.bytes().AsBinaryData(), tableGroupHandle, true, this.isXlsx() );
+    tableGroupHandle := TableGroupHandle::Create( this.FileName() );
+    tableGroupHandle := XLS::LoadTableGroupFromBinaryData( BinaryData::FromBase64EncodedString( this.Base64Str() ), tableGroupHandle, true, this.IsXlsx() );
+    
     sheets := tableGroupHandle.TableNames();
     
-    traverse ( sheets, Elements, sheetName, sheetName = "MatAttrSettingAndPlanningStrategy" ) {
+    traverse ( sheets, Elements, sheetName, sheetName = "MatAttrSettingAndPlanStrategy" ) {
       tableHandle := tableGroupHandle.Table( sheetName );
       tableXML := TableHandle::ExportXML( tableHandle );
       MatAttrSettingAndPlanStrategyDataTable::XMLImportMatAttrSettingAndPlanStrategyDataTableXMLHeaders(  tableXML );
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Method_saveData.qbl b/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Method_saveData.qbl
index de6f10d..362f5dd 100644
--- a/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Method_saveData.qbl
+++ b/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/Method_saveData.qbl
@@ -1,6 +1,6 @@
 Quintiq file version 2.0
 #parent: #root
-Method saveData
+Method SaveData
 {
   TextBody:
   [*
@@ -8,7 +8,7 @@
     if( this.MatAttrSettingAndPlanStrategyDataTable( relsize ) > 0 ) {
       traverse( this, MatAttrSettingAndPlanStrategyDataTable, table ) {
         traverse( table, MatAttrSettingAndPlanStrategyDataRow, row ) {
-          MatAttrSettingAndPlanStrategy::update( this.GlobalOTDTable(), row );
+          MatAttrSettingAndPlanStrategy::Update( this.GlobalOTDTable(), row, this.UserName() );
         }  
       }  
     }
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/StaticMethod_upload.qbl b/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/StaticMethod_upload.qbl
index bbb4453..be023c4 100644
--- a/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/StaticMethod_upload.qbl
+++ b/_Main/BL/Type_MatAttrSettingAndPlanStrategyInputSource/StaticMethod_upload.qbl
@@ -1,9 +1,10 @@
 Quintiq file version 2.0
 #parent: #root
-StaticMethod upload (
+StaticMethod Upload (
   GlobalOTDTable parent,
   String filePath,
-  BinaryValue bytes
+  String base64Str,
+  String userName
 ) as MatAttrSettingAndPlanStrategyInputSource
 {
   TextBody:
@@ -14,9 +15,10 @@
     fileName := filePath.Tokenize( "\" ).Element( filePath.Tokenize( "\" ).Size() - 1 );
     info( "fileName : " + fileName );
     inputSource := parent.MatAttrSettingAndPlanStrategyInputSource( relnew,
-                                              fileName := fileName,
-                                              bytes := bytes, 
-                                              isXlsx := fileName.EndsWith( "xlsx" ));
+                                                                    FileName := fileName,
+                                                                    Base64Str := base64Str, 
+                                                                    IsXlsx := fileName.EndsWith( "xlsx" ), 
+                                                                    UserName := userName );
     
     return inputSource;
   *]
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/Attribute_FlagGeneric.qbl b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/Attribute_FlagGeneric.qbl
index e2bacd6..acdc390 100644
--- a/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/Attribute_FlagGeneric.qbl
+++ b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/Attribute_FlagGeneric.qbl
@@ -3,6 +3,10 @@
 Attribute FlagGeneric
 {
   #keys: '3[414384.0.763764895][414384.0.763764894][414384.0.763764896]'
-  Description: '鏄惁閫氱敤'
+  Description:
+  [*
+    鏄惁閫氱敤
+    涓撶敤 & 閫氱敤
+  *]
   ValueType: String
 }
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/Attribute_FlagLongTerm.qbl b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/Attribute_FlagLongTerm.qbl
index 7302e5e..bf68daa 100644
--- a/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/Attribute_FlagLongTerm.qbl
+++ b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/Attribute_FlagLongTerm.qbl
@@ -3,6 +3,10 @@
 Attribute FlagLongTerm
 {
   #keys: '3[414384.0.763764885][414384.0.763764884][414384.0.763764886]'
-  Description: '鏄惁闀挎湡'
+  Description:
+  [*
+    鏄惁闀挎湡
+    闀垮懆鏈� & 鐭懆鏈�
+  *]
   ValueType: String
 }
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/Attribute_PlanningStrategyAuto.qbl b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/Attribute_PlanningStrategyAuto.qbl
index b0309cb..2c9ba97 100644
--- a/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/Attribute_PlanningStrategyAuto.qbl
+++ b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/Attribute_PlanningStrategyAuto.qbl
@@ -3,6 +3,10 @@
 Attribute PlanningStrategyAuto
 {
   #keys: '3[414384.0.759444687][414384.0.759444686][414384.0.759444688]'
-  Description: '鑷姩璁″垝绛栫暐'
+  Description:
+  [*
+    鑷姩璁″垝绛栫暐
+    JIT & 瀹夊叏搴撳瓨 & VMI
+  *]
   ValueType: String
 }
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/Function_CalcMinProdDeliverLT.qbl b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/Function_CalcMinProdDeliverLT.qbl
new file mode 100644
index 0000000..c02ef61
--- /dev/null
+++ b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/Function_CalcMinProdDeliverLT.qbl
@@ -0,0 +1,17 @@
+Quintiq file version 2.0
+#parent: #root
+Function CalcMinProdDeliverLT
+{
+  TextBody:
+  [*
+    // yypsybs Sep-8-2023 (created)
+    
+    value := 0.0;
+    
+    if( this.MatAttrSettingAndPlanStrategyDetail( relsize ) <> 0 ) {
+      value := guard( min( this, MatAttrSettingAndPlanStrategyDetail, detail, detail.StandardLT() ) , 0.0 );
+    }
+    
+    this.MinProdDeliverLT( value );
+  *]
+}
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/Function_CalcPlanningStrategyAuto.qbl b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/Function_CalcPlanningStrategyAuto.qbl
new file mode 100644
index 0000000..74fd0ee
--- /dev/null
+++ b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/Function_CalcPlanningStrategyAuto.qbl
@@ -0,0 +1,23 @@
+Quintiq file version 2.0
+#parent: #root
+Function CalcPlanningStrategyAuto
+{
+  TextBody:
+  [*
+    // yypsybs Sep-8-2023 (created)
+    
+    value := "";
+    
+    if( this.FlagLongTerm() = "闀垮懆鏈�" and this.FlagGeneric() = "涓撶敤" ) {
+      value := "JIT";  
+    } else if ( this.FlagLongTerm() = "闀垮懆鏈�" and this.FlagGeneric() = "閫氱敤" ) {
+      value := "瀹夊叏搴撳瓨";  
+    } else if ( this.FlagLongTerm() = "鐭懆鏈�" and this.FlagGeneric() = "涓撶敤" ) {
+      value := "JIT";  
+    } else if ( this.FlagLongTerm() = "鐭懆鏈�" and this.FlagGeneric() = "閫氱敤" ) {
+      value := "VMI";  
+    }
+    
+    this.PlanningStrategyAuto( value );
+  *]
+}
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/Function_CalcProductCount.qbl b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/Function_CalcProductCount.qbl
new file mode 100644
index 0000000..e03f766
--- /dev/null
+++ b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/Function_CalcProductCount.qbl
@@ -0,0 +1,13 @@
+Quintiq file version 2.0
+#parent: #root
+Function CalcProductCount
+{
+  TextBody:
+  [*
+    // yypsybs Sep-8-2023 (created)
+    
+    value := counter( this, MatAttrSettingAndPlanStrategyDetail, item, true );
+    
+    this.ProductCount( value );
+  *]
+}
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_CreateIfNotExist.qbl b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_CreateIfNotExist.qbl
new file mode 100644
index 0000000..c69081c
--- /dev/null
+++ b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_CreateIfNotExist.qbl
@@ -0,0 +1,31 @@
+Quintiq file version 2.0
+#parent: #root
+StaticMethod CreateIfNotExist (
+  GlobalOTDTable parent,
+  String matCode,
+  String matName,
+  String matType,
+  Real matArrivalLT,
+  String flagGeneric,
+  String flagLongTerm
+) as MatAttrSettingAndPlanStrategy
+{
+  TextBody:
+  [*
+    // yypsybs Sep-8-2023 (created)
+    value := MatAttrSettingAndPlanStrategy::GetExistByMatCode( parent, matCode );
+    if( isnull( value ) ) {
+      value := parent.MatAttrSettingAndPlanStrategy( relnew, 
+                                                     MatCode := matCode, 
+                                                     MatName := matName,
+                                                     MatType := matType,
+                                                     MatArrivalLT := matArrivalLT, 
+                                                     FlagGeneric := flagGeneric, 
+                                                     FlagLongTerm := flagLongTerm,
+                                                     PlanningStrategyCustom := "",
+                                                     UpdateBy := "",
+                                                     UpdateTime := DateTime::MinDateTime() );
+    }
+    return value;
+  *]
+}
diff --git "a/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_deleteIfExistByMatCode\043136.qbl" "b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_DeleteIfExistByMatCode\043526.qbl"
similarity index 73%
rename from "_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_deleteIfExistByMatCode\043136.qbl"
rename to "_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_DeleteIfExistByMatCode\043526.qbl"
index 7d22871..7d84d24 100644
--- "a/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_deleteIfExistByMatCode\043136.qbl"
+++ "b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_DeleteIfExistByMatCode\043526.qbl"
@@ -1,14 +1,14 @@
 Quintiq file version 2.0
 #parent: #root
-StaticMethod deleteIfExistByMatCode (
+StaticMethod DeleteIfExistByMatCode (
   GlobalOTDTable parent,
-  Strings matCodes
+  Strings matCode
 )
 {
   TextBody:
   [*
     // yypsybs Jul-2-2023 (created)
-    toDels := selectset( parent, MatAttrSettingAndPlanStrategy, item, true, matCodes.Find( item.MatCode() ) <> -1 );
+    toDels := selectset( parent, MatAttrSettingAndPlanStrategy, item, true, matCode.Find( item.MatCode() ) >= 0 );
     if( toDels.Size() > 0 ) {
       traverse( toDels, Elements, toDel ) {
         toDel.Delete();
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_delete.qbl b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_delete.qbl
index 46c6957..3c9e3f1 100644
--- a/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_delete.qbl
+++ b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_delete.qbl
@@ -1,6 +1,6 @@
 Quintiq file version 2.0
 #parent: #root
-StaticMethod delete (
+StaticMethod Delete (
   MatAttrSettingAndPlanStrategys toDels
 )
 {
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_deleteIfExistByMatCode.qbl b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_deleteIfExistByMatCode.qbl
index 0defbb4..4cd01e5 100644
--- a/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_deleteIfExistByMatCode.qbl
+++ b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_deleteIfExistByMatCode.qbl
@@ -1,6 +1,6 @@
 Quintiq file version 2.0
 #parent: #root
-StaticMethod deleteIfExistByMatCode (
+StaticMethod DeleteIfExistByMatCode (
   GlobalOTDTable parent,
   String matCode
 )
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_getExistByMatCode.qbl b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_getExistByMatCode.qbl
index 31f507e..c0e174e 100644
--- a/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_getExistByMatCode.qbl
+++ b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_getExistByMatCode.qbl
@@ -1,6 +1,6 @@
 Quintiq file version 2.0
 #parent: #root
-StaticMethod getExistByMatCode (
+StaticMethod GetExistByMatCode (
   GlobalOTDTable parent,
   String matCode
 ) as MatAttrSettingAndPlanStrategy
diff --git a/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_update.qbl b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_update.qbl
index 8294a1c..44ea303 100644
--- a/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_update.qbl
+++ b/_Main/BL/Type_MatAttrSettingAndPlanningStrategy/StaticMethod_update.qbl
@@ -1,14 +1,16 @@
 Quintiq file version 2.0
 #parent: #root
-StaticMethod update (
+StaticMethod Update (
   GlobalOTDTable parent,
-  MatAttrSettingAndPlanStrategyDataRow excelRow
+  MatAttrSettingAndPlanStrategyDataRow excelRow,
+  String userName
 ) as MatAttrSettingAndPlanStrategy
 {
   TextBody:
   [*
-    fields := MatAttrSettingAndPlanStrategyDataTable::exportFields();
-    headers := MatAttrSettingAndPlanStrategyDataTable::expectedHeaders();
+    fields := MatAttrSettingAndPlanStrategyDataTable::ExportFields();
+    headers := MatAttrSettingAndPlanStrategyDataTable::ExpectedHeaders();
+    //info( "--------SaveData--------" );
     // 鎵惧緟鏇存柊璁板綍
     toUpdate := null( MatAttrSettingAndPlanStrategy );
     matCode := "";
@@ -16,37 +18,50 @@
       header := headers.Element( i );
       cell := excelRow.MatAttrSettingAndPlanStrategyDataCell( relget ).Element( i );
       if( cell.MatAttrSettingAndPlanStrategyDataColumn().name() <> header ) {
+        FeedbackObject::LocalFeedback().AddHard( "the column with index " + [String]i + " should be " + header + ", but found " + cell.MatAttrSettingAndPlanStrategyDataColumn().name() );
         error( "the column with index " + [String]i + " should be " + header + ", but found " + cell.MatAttrSettingAndPlanStrategyDataColumn().name() );
       }
       if( cell.MatAttrSettingAndPlanStrategyDataColumn().name() = "鐗╂枡缂栫爜" and cell.value() <> "") {
         matCode := cell.value();
-        toUpdate := MatAttrSettingAndPlanStrategy::getExistByMatCode( parent, matCode );
+        toUpdate := MatAttrSettingAndPlanStrategy::GetExistByMatCode( parent, matCode );
+        if( isnull( toUpdate ) ) {
+          FeedbackObject::LocalFeedback().AddHard( "get MatAttrSettingAndPlanStrategy by matCode [" + matCode + "] failed" );
+          error( "get MatAttrSettingAndPlanStrategy by matCode [" + matCode + "] failed" );
+        }
       }
     }
     if( not isnull( toUpdate ) ) {
       // 瀵规瘮宸紓
       for( i := 0; i < fields.Size(); i++ ) {
-        header := headers.Element( i );
+    //    header := headers.Element( i );
         cell := excelRow.MatAttrSettingAndPlanStrategyDataCell( relget ).Element( i );
         fieldName := fields.Element( i );
-        field := Reflection::FindAttribute( "MatAttrSettingAndPlanningStrategy", fieldName);
+        field := Reflection::FindAttribute( "MatAttrSettingAndPlanStrategy", fieldName);
+        if( isnull( field ) ) {
+          FeedbackObject::LocalFeedback().AddHard( "MatAttrSettingAndPlanStrategy does not have field " + fieldName );
+          error( "MatAttrSettingAndPlanStrategy does not have field " + fieldName );
+        }
+    //    info( "========header:" + header + "========" )
+    //    info( "========fieldName:" + fieldName + "========" )
+    //    info( "========cell:" + cell.value() + "========" )
         if( fieldName = "MatName" or fieldName = "MatType" or fieldName = "FlagLongTerm" or fieldName = "FlagGeneric" or fieldName = "PlanningStrategyAuto" ) {
-           fieldValue := guard( field.GetString( toUpdate ), "" );
-           if( fieldValue <> cell.value() ) {
-             error( "column " + header + " does not support to be changed" );
-           }
+          // do nothing
         } else if( fieldName = "MatArrivalLT" or fieldName = "ProductCount" or fieldName = "MinProdDeliverLT" ) {
-           fieldRealValue := guard( field.GetReal( toUpdate ), 0.0 );
-           if( fieldRealValue <> [Real]cell.value() ) {
-             error( "column " + header + " does not support to be changed" );
-           }
+          // do nothing
         } else if( fieldName = "PlanningStrategyCustom" ) {
-          fieldValue := guard( field.GetString( toUpdate ), "" );
-          toUpdate.PlanningStrategyCustom( fieldValue );
+          if( cell.value() <> "VMI" and cell.value() <> "瀹夊叏搴撳瓨" and cell.value() <> "VIT" ) {
+            FeedbackObject::LocalFeedback().AddHard( "unsupported PlanningStrategyCustom : " + cell.value() );
+            error( "unsupported PlanningStrategyCustom : " + cell.value() );
+          } else if( cell.value() <> toUpdate.PlanningStrategyCustom() ) {
+            toUpdate.PlanningStrategyCustom( cell.value() );
+            toUpdate.UpdateBy( userName );
+            toUpdate.UpdateTime( DateTime::Now() );
+          }
         }
       }
     } else {
-      error( "no record with matCode : " + matCode )
+      FeedbackObject::LocalFeedback().AddHard( "no record with matCode : " + matCode );
+      error( "no record with matCode : " + matCode );
     }
     
     return toUpdate;
diff --git a/_Main/UI/MacroPlannerWebApp/Component_DialogEdit/Component_pnlActions.def b/_Main/UI/MacroPlannerWebApp/Component_DialogEdit/Component_pnlActions.def
new file mode 100644
index 0000000..16082f0
--- /dev/null
+++ b/_Main/UI/MacroPlannerWebApp/Component_DialogEdit/Component_pnlActions.def
@@ -0,0 +1,40 @@
+Quintiq file version 2.0
+Component pnlActions
+{
+  #keys: '[414384.0.770880997]'
+  BaseType: 'WebPanel'
+  Children:
+  [
+    Component btnOk
+    {
+      #keys: '[414384.0.770881001]'
+      BaseType: 'WebButton'
+      Properties:
+      [
+        Label: 'OK'
+        Taborder: 0
+      ]
+    }
+    Component btnCancel
+    {
+      #keys: '[414384.0.770881003]'
+      BaseType: 'WebButton'
+      Properties:
+      [
+        Label: 'Cancel'
+        Taborder: 1
+      ]
+    }
+  ]
+  Properties:
+  [
+    Alignment: 'trailing'
+    Border: true
+    ExcludeFromActiveComponent: true
+    FixedSize: true
+    Orientation: 'horizontal'
+    Padding: 'true'
+    Style: 'footer'
+    Taborder: 1
+  ]
+}
diff --git a/_Main/UI/MacroPlannerWebApp/Component_DialogEdit/Component_pnlContent.def b/_Main/UI/MacroPlannerWebApp/Component_DialogEdit/Component_pnlContent.def
new file mode 100644
index 0000000..802f9f1
--- /dev/null
+++ b/_Main/UI/MacroPlannerWebApp/Component_DialogEdit/Component_pnlContent.def
@@ -0,0 +1,27 @@
+Quintiq file version 2.0
+Component pnlContent
+{
+  #keys: '[414384.0.770880995]'
+  BaseType: 'WebPanel'
+  Children:
+  [
+    Component dropDownPlanningStrategyCustom
+    {
+      #keys: '[414384.0.770871903]'
+      BaseType: 'WebDropDownStringList'
+      Properties:
+      [
+        AllowEmpty: true
+        DataBinding: 'DataHolderDialogData.Data.PlanningStrategyCustom'
+        Label: 'PlanningStrategyCustom'
+        Strings: 'JIT;瀹夊叏搴撳瓨;VMI'
+        Taborder: 0
+      ]
+    }
+  ]
+  Properties:
+  [
+    Padding: 'true'
+    Taborder: 0
+  ]
+}
diff --git a/_Main/UI/MacroPlannerWebApp/Component_DialogEdit/Method_Edit.def b/_Main/UI/MacroPlannerWebApp/Component_DialogEdit/Method_Edit.def
new file mode 100644
index 0000000..20760cd
--- /dev/null
+++ b/_Main/UI/MacroPlannerWebApp/Component_DialogEdit/Method_Edit.def
@@ -0,0 +1,17 @@
+Quintiq file version 2.0
+#parent: #root
+Method Edit (
+  MatAttrSettingAndPlanStrategy item
+) id:Method_DialogEditMatAttrSettingAndPlanStrategy_Edit
+{
+  #keys: '[414384.0.772161633]'
+  Body:
+  [*
+    // Edit uom
+    data := shadow( item );
+    
+    DataHolderDialogData.Data( &data );
+    
+    ApplicationMacroPlanner.ShowFormModal( this );
+  *]
+}
diff --git a/_Main/UI/MacroPlannerWebApp/Component_DialogEdit/Method_OnOK.def b/_Main/UI/MacroPlannerWebApp/Component_DialogEdit/Method_OnOK.def
new file mode 100644
index 0000000..d26a7a1
--- /dev/null
+++ b/_Main/UI/MacroPlannerWebApp/Component_DialogEdit/Method_OnOK.def
@@ -0,0 +1,16 @@
+Quintiq file version 2.0
+#parent: #root
+Method OnOK () id:Method_DialogEditMatAttrSettingAndPlanStrategy_OnOK
+{
+  #keys: '[414384.0.772193415]'
+  Body:
+  [*
+    // On ok
+    Form.ApplyChanges();
+    
+    data := DataHolderDialogData.Data();
+    data.WrappedInstance().PlanningStrategyCustom( dropDownPlanningStrategyCustom.Text() );
+    
+    Form.Close();
+  *]
+}
diff --git a/_Main/UI/MacroPlannerWebApp/Component_DialogEdit/Response_pnlActions_btnCancel_OnClick.def b/_Main/UI/MacroPlannerWebApp/Component_DialogEdit/Response_pnlActions_btnCancel_OnClick.def
new file mode 100644
index 0000000..179c75d
--- /dev/null
+++ b/_Main/UI/MacroPlannerWebApp/Component_DialogEdit/Response_pnlActions_btnCancel_OnClick.def
@@ -0,0 +1,15 @@
+Quintiq file version 2.0
+#parent: pnlActions/btnCancel
+Response OnClick () id:Response_pnlActions_btnCancel_OnClick
+{
+  #keys: '[414384.0.770881007]'
+  DefinitionID: 'Responsedef_WebButton_OnClick'
+  GroupServerCalls: true
+  QuillAction
+  {
+    Body:
+    [*
+      Form.Close();
+    *]
+  }
+}
diff --git a/_Main/UI/MacroPlannerWebApp/Component_DialogEdit/Response_pnlActions_btnOk_OnClick.def b/_Main/UI/MacroPlannerWebApp/Component_DialogEdit/Response_pnlActions_btnOk_OnClick.def
new file mode 100644
index 0000000..d6ccb93
--- /dev/null
+++ b/_Main/UI/MacroPlannerWebApp/Component_DialogEdit/Response_pnlActions_btnOk_OnClick.def
@@ -0,0 +1,15 @@
+Quintiq file version 2.0
+#parent: pnlActions/btnOk
+Response OnClick () id:Response_pnlActions_btnOk_OnClick
+{
+  #keys: '[414384.0.770881006]'
+  DefinitionID: 'Responsedef_WebButton_OnClick'
+  GroupServerCalls: true
+  QuillAction
+  {
+    Body:
+    [*
+      Form.OnOK();
+    *]
+  }
+}
diff --git a/_Main/UI/MacroPlannerWebApp/Component_DialogEdit/_ROOT_Component_DialogEditMatAttrSettingAndPlanStrategy.def b/_Main/UI/MacroPlannerWebApp/Component_DialogEdit/_ROOT_Component_DialogEditMatAttrSettingAndPlanStrategy.def
new file mode 100644
index 0000000..bc7540c
--- /dev/null
+++ b/_Main/UI/MacroPlannerWebApp/Component_DialogEdit/_ROOT_Component_DialogEditMatAttrSettingAndPlanStrategy.def
@@ -0,0 +1,31 @@
+Quintiq file version 2.0
+#root
+#parent: MacroPlannerWebApp
+OrphanComponent DialogEditMatAttrSettingAndPlanStrategy
+{
+  #keys: '[414384.0.770880993]'
+  BaseType: 'WebForm'
+  Children:
+  [
+    #child: pnlContent
+    #child: pnlActions
+    Component DataHolderDialogData
+    {
+      #keys: '[414384.0.772100860]'
+      BaseType: 'WebDataHolder'
+      Databinding: 'shadow[MatAttrSettingAndPlanStrategy]*'
+      Properties:
+      [
+        Taborder: 2
+      ]
+    }
+  ]
+  Properties:
+  [
+    Alignment: 'trailing'
+    EnterButton: 'btnOk'
+    EscapeButton: 'btnCancel'
+    ExcludeFromActiveComponent: true
+    Padding: 'false'
+  ]
+}
diff --git a/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Component_ListMatAttrSettingAndPlanStrategy.def b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Component_ListMatAttrSettingAndPlanStrategy.def
new file mode 100644
index 0000000..37dde34
--- /dev/null
+++ b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Component_ListMatAttrSettingAndPlanStrategy.def
@@ -0,0 +1,105 @@
+Quintiq file version 2.0
+Component ListMatAttrSettingAndPlanStrategy
+{
+  #keys: '[414384.0.769370441]'
+  BaseType: 'WebList'
+  Children:
+  [
+    Component DataExtractorMatAttrSettingAndPlanStrategy
+    {
+      #keys: '[414384.0.769370442]'
+      BaseType: 'WebDataExtractor'
+      Properties:
+      [
+        DataType: 'GlobalOTDTable'
+        Source: 'GlobalOTDTable'
+        Taborder: 0
+        Transformation: 'MatAttrSettingAndPlanStrategy'
+      ]
+    }
+    Component DataSetLevelMatAttrSettingAndPlanStrategy
+    {
+      #keys: '[414384.0.769370443]'
+      BaseType: 'WebDataSetLevel'
+      Children:
+      [
+        #child: listContextMenuMatAttrSettingAndPlanStrategy
+      ]
+      Properties:
+      [
+        Columns: '[{"attribute":{"classtype":"WebApiDefinitionAttributeDataMember","columnid":"MatCode","title":"MatCode","subtotals":"","tooltip":"","width":-1,"display":"shown","editable":false,"attribute":"MatCode"}},{"attribute":{"classtype":"WebApiDefinitionAttributeDataMember","columnid":"MatName","title":"MatName","subtotals":"","tooltip":"","width":-1,"display":"shown","editable":false,"attribute":"MatName"}},{"attribute":{"classtype":"WebApiDefinitionAttributeDataMember","columnid":"MatType","title":"MatType","subtotals":"","tooltip":"","width":-1,"display":"shown","editable":false,"attribute":"MatType"}},{"attribute":{"classtype":"WebApiDefinitionAttributeDataMember","columnid":"MatArrivalLT","title":"MatArrivalLT","subtotals":"","tooltip":"","width":-1,"display":"shown","editable":false,"attribute":"MatArrivalLT"}},{"attribute":{"classtype":"WebApiDefinitionAttributeDataMember","columnid":"ProductCount","title":"ProductCount","subtotals":"","tooltip":"","width":-1,"display":"shown","editable":false,"attribute":"ProductCount"}},{"attribute":{"classtype":"WebApiDefinitionAttributeDataMember","columnid":"MinProdDeliverLT","title":"MinProdDeliverLT","subtotals":"","tooltip":"","width":-1,"display":"shown","editable":false,"attribute":"MinProdDeliverLT"}},{"attribute":{"classtype":"WebApiDefinitionAttributeDataMember","columnid":"FlagLongTerm","title":"FlagLongTerm","subtotals":"","tooltip":"","width":-1,"display":"shown","editable":false,"attribute":"FlagLongTerm"}},{"attribute":{"classtype":"WebApiDefinitionAttributeDataMember","columnid":"FlagGeneric","title":"FlagGeneric","subtotals":"","tooltip":"","width":-1,"display":"shown","editable":false,"attribute":"FlagGeneric"}},{"attribute":{"classtype":"WebApiDefinitionAttributeDataMember","columnid":"PlanningStrategyAuto","title":"PlanningStrategyAuto","subtotals":"","tooltip":"","width":-1,"display":"shown","editable":false,"attribute":"PlanningStrategyAuto"}},{"attribute":{"classtype":"WebApiDefinitionAttributeDataMember","columnid":"PlanningStrategyCustom","title":"PlanningStrategyCustom","subtotals":"","tooltip":"","width":-1,"display":"shown","editable":false,"attribute":"PlanningStrategyCustom"}},{"attribute":{"classtype":"WebApiDefinitionAttributeDataMember","columnid":"UpdateBy","title":"UpdateBy","subtotals":"","tooltip":"","width":-1,"display":"shown","editable":false,"attribute":"UpdateBy"}},{"attribute":{"classtype":"WebApiDefinitionAttributeDataMember","columnid":"UpdateTime","title":"UpdateTime","subtotals":"","tooltip":"","width":-1,"display":"shown","editable":false,"attribute":"UpdateTime"}}]'
+        ContextMenu: 'listContextMenuMatAttrSettingAndPlanStrategy'
+        SortCriteria: 'MatCode'
+        Taborder: 1
+      ]
+    }
+    #child: listActionBarPageMatAttrSettingAndPlanStrategy
+  ]
+  Properties:
+  [
+    Taborder: 2
+  ]
+  ResponseDefinitions:
+  [
+    DelegatedResponseDefinition OnClick id:Responsedef_ListMatAttrSettingAndPlanStrategy_WebMenu_OnClick
+    {
+      #keys: '[414384.0.769370436]'
+      Initiator: 'WebMenu'
+      IsInherited: false
+      ResponseType: 'OnClick'
+      Arguments:
+      [
+        ResponseDefinitionArgument selection
+        {
+          #keys: '[2651.0.25404553]'
+          Binding: 'this.Selection()'
+        }
+      ]
+    }
+    DelegatedResponseDefinition OnClick id:Responsedef_ListMatAttrSettingAndPlanStrategy_WebButton_OnClick
+    {
+      #keys: '[414384.0.769370435]'
+      Initiator: 'WebButton'
+      IsInherited: false
+      ResponseType: 'OnClick'
+      Arguments:
+      [
+        ResponseDefinitionArgument selection
+        {
+          #keys: '[6763.0.7953347]'
+          Binding: 'this.Selection()'
+        }
+      ]
+    }
+    DelegatedResponseDefinition OnClick id:Responsedef_ListMatAttrSettingAndPlanStrategy_WebMenu_OnClick_106
+    {
+      #keys: '[414384.0.769370434]'
+      Initiator: 'WebMenu'
+      IsInherited: false
+      ResponseType: 'OnClick'
+      Arguments:
+      [
+        ResponseDefinitionArgument checked
+        {
+          #keys: '[6763.0.7953392]'
+          Binding: 'this.Checked()'
+        }
+      ]
+    }
+    DelegatedResponseDefinition OnClick id:Responsedef_ListMatAttrSettingAndPlanStrategy_WebButton_OnClick_415
+    {
+      #keys: '[414384.0.769370433]'
+      Initiator: 'WebButton'
+      IsInherited: false
+      ResponseType: 'OnClick'
+      Arguments:
+      [
+        ResponseDefinitionArgument checked
+        {
+          #keys: '[6763.0.7953437]'
+          Binding: 'this.Checked()'
+        }
+      ]
+    }
+  ]
+}
diff --git a/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Component_listActionBarPageMatAttrSettingAndPlanStrategy.def b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Component_listActionBarPageMatAttrSettingAndPlanStrategy.def
new file mode 100644
index 0000000..524e038
--- /dev/null
+++ b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Component_listActionBarPageMatAttrSettingAndPlanStrategy.def
@@ -0,0 +1,10 @@
+Quintiq file version 2.0
+Component listActionBarPageMatAttrSettingAndPlanStrategy
+{
+  #keys: '[414384.0.769370448]'
+  BaseType: 'listActionBarPage'
+  Properties:
+  [
+    Taborder: 2
+  ]
+}
diff --git a/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Component_listContextMenuMatAttrSettingAndPlanStrategy.def b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Component_listContextMenuMatAttrSettingAndPlanStrategy.def
new file mode 100644
index 0000000..3415621
--- /dev/null
+++ b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Component_listContextMenuMatAttrSettingAndPlanStrategy.def
@@ -0,0 +1,27 @@
+Quintiq file version 2.0
+Component listContextMenuMatAttrSettingAndPlanStrategy
+{
+  #keys: '[414384.0.769370444]'
+  BaseType: 'listContextMenu'
+  Children:
+  [
+    Component MenuEdit
+    {
+      #keys: '[414384.0.769370445]'
+      BaseType: 'WebMenu'
+      Properties:
+      [
+        BindOnDoubleClick: true
+        DelegationID: 'ActionBarData_Edit'
+        Image: 'PENCIL'
+        Shortcut: 'Enter'
+        Taborder: 3
+        Title: 'Edit...'
+      ]
+    }
+  ]
+  Properties:
+  [
+    Taborder: 0
+  ]
+}
diff --git a/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Response_ButtonMatAttrSettingAndPlanStrategyExport_OnClick.def b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Response_ButtonMatAttrSettingAndPlanStrategyExport_OnClick.def
new file mode 100644
index 0000000..73a180c
--- /dev/null
+++ b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Response_ButtonMatAttrSettingAndPlanStrategyExport_OnClick.def
@@ -0,0 +1,18 @@
+Quintiq file version 2.0
+#parent: ButtonMatAttrSettingAndPlanStrategyExport
+Response OnClick () id:Response_FormMatAttrSettingAndPlanStrategy_ButtonMatAttrSettingAndPlanStrategyExport_OnClick
+{
+  #keys: '[414384.0.772313427]'
+  CanBindMultiple: false
+  DefinitionID: 'Responsedef_WebButton_OnClick'
+  QuillAction
+  {
+    Body:
+    [*
+      info( "ButtonMatAttrSettingAndPlanStrategyExport.OnClick" );
+      Application.Download( "MatAttrSettingAndPlanningStrategy.xlsx", 
+                            MatAttrSettingAndPlanStrategyDataTable::Export( GlobalOTDTable ) );
+    *]
+    GroupServerCalls: false
+  }
+}
diff --git a/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Response_ButtonMatAttrSettingAndPlanStrategyImport_OnClick.def b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Response_ButtonMatAttrSettingAndPlanStrategyImport_OnClick.def
new file mode 100644
index 0000000..183442b
--- /dev/null
+++ b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Response_ButtonMatAttrSettingAndPlanStrategyImport_OnClick.def
@@ -0,0 +1,32 @@
+Quintiq file version 2.0
+#parent: ButtonMatAttrSettingAndPlanStrategyImport
+Response OnClick () id:Response_FormMatAttrSettingAndPlanStrategy_ButtonMatAttrSettingAndPlanStrategyImport_OnClick
+{
+  #keys: '[414384.0.772313506]'
+  CanBindMultiple: false
+  DefinitionID: 'Responsedef_WebButton_OnClick'
+  QuillAction
+  {
+    Body:
+    [*
+      try {
+        uploadJson := Application.GetFile();
+        json := JSON::Parse( uploadJson );
+        if( json.IsArray() or json.Size() = 0 ) {
+          error( "please select one .xls or .xlsx file" ); 
+        }
+        name := json.Get( "name" ).GetString();
+        base64Data := json.Get( "data" ).GetString();
+        inputSource := MatAttrSettingAndPlanStrategyInputSource::Upload( GlobalOTDTable, name, base64Data, ApplicationMacroPlanner.GetUserName() );
+        inputSource.ParseTable();
+        inputSource.SaveData();
+      } onerror {
+        info( e.GeneralInformation() );
+        info( e.DetailedInformation() );
+        info( e.DeveloperInformation() );
+        WebMessageBox::Error( e.GeneralInformation() );
+      }
+    *]
+    GroupServerCalls: false
+  }
+}
diff --git a/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Response_ListMatAttrSettingAndPlanStrategy_MenuEdit_OnClick.def b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Response_ListMatAttrSettingAndPlanStrategy_MenuEdit_OnClick.def
new file mode 100644
index 0000000..f0014e8
--- /dev/null
+++ b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Response_ListMatAttrSettingAndPlanStrategy_MenuEdit_OnClick.def
@@ -0,0 +1,20 @@
+Quintiq file version 2.0
+#parent: ListMatAttrSettingAndPlanStrategy
+Response OnClick (
+  MatAttrSettingAndPlanStrategy selection
+) id:Response_ListMatAttrSettingAndPlanStrategy_MenuEdit_OnClick
+{
+  #keys: '[414384.0.769370438]'
+  CanBindMultiple: false
+  DefinitionID => /ListMatAttrSettingAndPlanStrategy/Responsedef_ListMatAttrSettingAndPlanStrategy_WebMenu_OnClick
+  GroupServerCalls: true
+  Initiator: 'MenuEdit'
+  QuillAction
+  {
+    Body:
+    [*
+      dlg := construct( DialogEditMatAttrSettingAndPlanStrategy );
+      dlg.Edit( selection );
+    *]
+  }
+}
diff --git a/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Response_OnCreated.def b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Response_OnCreated.def
new file mode 100644
index 0000000..461fa7c
--- /dev/null
+++ b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/Response_OnCreated.def
@@ -0,0 +1,17 @@
+Quintiq file version 2.0
+#parent: #root
+Response OnCreated () id:Response_FormMatAttrSettingAndPlanStrategy_OnCreated
+{
+  #keys: '[414384.0.770811994]'
+  CanBindMultiple: false
+  DefinitionID: 'Responsedef_WebComponent_OnCreated'
+  GroupServerCalls: true
+  QuillAction
+  {
+    Body:
+    [*
+      GlobalOTDTable.InitTestData();
+      info( "FormMatAttrSettingAndPlanStrategy created" )
+    *]
+  }
+}
diff --git a/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/_ROOT_Component_FormMatAttrSettingAndPlanStrategy.def b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/_ROOT_Component_FormMatAttrSettingAndPlanStrategy.def
new file mode 100644
index 0000000..7d0618e
--- /dev/null
+++ b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategy/_ROOT_Component_FormMatAttrSettingAndPlanStrategy.def
@@ -0,0 +1,39 @@
+Quintiq file version 2.0
+#root
+#parent: MacroPlannerWebApp
+OrphanComponent FormMatAttrSettingAndPlanStrategy
+{
+  #keys: '[414384.0.767100500]'
+  BaseType: 'WebForm'
+  Children:
+  [
+    #child: ListMatAttrSettingAndPlanStrategy
+    Component ButtonMatAttrSettingAndPlanStrategyExport
+    {
+      #keys: '[414384.0.770831027]'
+      BaseType: 'WebButton'
+      Properties:
+      [
+        Image: 'EXPORT1'
+        Label: 'Export'
+        Taborder: 0
+      ]
+    }
+    Component ButtonMatAttrSettingAndPlanStrategyImport
+    {
+      #keys: '[414384.0.770831036]'
+      BaseType: 'WebButton'
+      Properties:
+      [
+        Image: 'IMPORT1'
+        Label: 'Import'
+        Taborder: 1
+      ]
+    }
+  ]
+  Properties:
+  [
+    Description: '4.11.鐗╂枡灞炴�ф爣绛捐瀹�&鐗╂枡璁″垝绛栫暐'
+    Title: '鐗╂枡灞炴�ф爣绛句笌鐗╂枡璁″垝绛栫暐'
+  ]
+}
diff --git "a/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategyDetail/Component_ListMatAttrSettingAndPlanStrategyDetail\04321.def" "b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategyDetail/Component_ListMatAttrSettingAndPlanStrategyDetail\04321.def"
new file mode 100644
index 0000000..6a99d11
--- /dev/null
+++ "b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategyDetail/Component_ListMatAttrSettingAndPlanStrategyDetail\04321.def"
@@ -0,0 +1,106 @@
+Quintiq file version 2.0
+Component ListMatAttrSettingAndPlanStrategyDetail id:ListMatAttrSettingAndPlanStrategyDetail_21
+{
+  #keys: '[414384.0.769370487]'
+  BaseType: 'WebList'
+  Children:
+  [
+    Component DataExtractorMatAttrSettingAndPlanStrategyDetail
+    {
+      #keys: '[414384.0.769370488]'
+      BaseType: 'WebDataExtractor'
+      Properties:
+      [
+        DataType: 'MatAttrSettingAndPlanStrategy'
+        ExtractionMode: 'Selected'
+        Source: 'FormMatAttrSettingAndPlanStrategy.ListMatAttrSettingAndPlanStrategy'
+        Taborder: 0
+        Transformation: 'MatAttrSettingAndPlanStrategyDetail'
+      ]
+    }
+    Component DataSetLevelMatAttrSettingAndPlanStrategyDetail
+    {
+      #keys: '[414384.0.769370489]'
+      BaseType: 'WebDataSetLevel'
+      Children:
+      [
+        #child: listContextMenuMatAttrSettingAndPlanStrategyDetail_1
+      ]
+      Properties:
+      [
+        Columns: '[{"attribute":{"classtype":"WebApiDefinitionAttributeDataMember","columnid":"MatCode","title":"MatCode","subtotals":"","tooltip":"","width":-1,"display":"shown","editable":false,"attribute":"MatCode"}},{"attribute":{"classtype":"WebApiDefinitionAttributeDataMember","columnid":"ProductCode","title":"ProductCode","subtotals":"","tooltip":"","width":-1,"display":"shown","editable":false,"attribute":"ProductCode"}},{"attribute":{"classtype":"WebApiDefinitionAttributeDataMember","columnid":"StandardLT","title":"StandardLT","subtotals":"","tooltip":"","width":-1,"display":"shown","editable":false,"attribute":"StandardLT"}},{"attribute":{"classtype":"WebApiDefinitionAttributeDataMember","columnid":"ProductDesc","title":"ProductDesc","subtotals":"","tooltip":"","width":-1,"display":"shown","editable":false,"attribute":"ProductDesc"}},{"attribute":{"classtype":"WebApiDefinitionAttributeDataMember","columnid":"Comment","title":"Comment","subtotals":"","tooltip":"","width":-1,"display":"shown","editable":false,"attribute":"Comment"}}]'
+        ContextMenu: 'listContextMenuMatAttrSettingAndPlanStrategyDetail'
+        SortCriteria: 'MatCode;ProductCode'
+        Taborder: 1
+      ]
+    }
+    #child: listActionBarPageMatAttrSettingAndPlanStrategyDetail_1
+  ]
+  Properties:
+  [
+    Taborder: 0
+  ]
+  ResponseDefinitions:
+  [
+    DelegatedResponseDefinition OnClick id:Responsedef_ListMatAttrSettingAndPlanStrategyDetail_21_WebMenu_OnClick
+    {
+      #keys: '[414384.0.769370482]'
+      Initiator: 'WebMenu'
+      IsInherited: false
+      ResponseType: 'OnClick'
+      Arguments:
+      [
+        ResponseDefinitionArgument selection
+        {
+          #keys: '[2651.0.25404553]'
+          Binding: 'this.Selection()'
+        }
+      ]
+    }
+    DelegatedResponseDefinition OnClick id:Responsedef_ListMatAttrSettingAndPlanStrategyDetail_21_WebButton_OnClick
+    {
+      #keys: '[414384.0.769370481]'
+      Initiator: 'WebButton'
+      IsInherited: false
+      ResponseType: 'OnClick'
+      Arguments:
+      [
+        ResponseDefinitionArgument selection
+        {
+          #keys: '[6763.0.7953347]'
+          Binding: 'this.Selection()'
+        }
+      ]
+    }
+    DelegatedResponseDefinition OnClick id:Responsedef_ListMatAttrSettingAndPlanStrategyDetail_21_WebMenu_OnClick_737
+    {
+      #keys: '[414384.0.769370480]'
+      Initiator: 'WebMenu'
+      IsInherited: false
+      ResponseType: 'OnClick'
+      Arguments:
+      [
+        ResponseDefinitionArgument checked
+        {
+          #keys: '[6763.0.7953392]'
+          Binding: 'this.Checked()'
+        }
+      ]
+    }
+    DelegatedResponseDefinition OnClick id:Responsedef_ListMatAttrSettingAndPlanStrategyDetail_21_WebButton_OnClick_456
+    {
+      #keys: '[414384.0.769370479]'
+      Initiator: 'WebButton'
+      IsInherited: false
+      ResponseType: 'OnClick'
+      Arguments:
+      [
+        ResponseDefinitionArgument checked
+        {
+          #keys: '[6763.0.7953437]'
+          Binding: 'this.Checked()'
+        }
+      ]
+    }
+  ]
+}
diff --git "a/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategyDetail/Component_listActionBarPageMatAttrSettingAndPlanStrategyDetail\0431.def" "b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategyDetail/Component_listActionBarPageMatAttrSettingAndPlanStrategyDetail\0431.def"
new file mode 100644
index 0000000..c48d2ee
--- /dev/null
+++ "b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategyDetail/Component_listActionBarPageMatAttrSettingAndPlanStrategyDetail\0431.def"
@@ -0,0 +1,10 @@
+Quintiq file version 2.0
+Component listActionBarPageMatAttrSettingAndPlanStrategyDetail id:listActionBarPageMatAttrSettingAndPlanStrategyDetail_1
+{
+  #keys: '[414384.0.769370494]'
+  BaseType: 'listActionBarPage'
+  Properties:
+  [
+    Taborder: 2
+  ]
+}
diff --git "a/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategyDetail/Component_listContextMenuMatAttrSettingAndPlanStrategyDetail\0431.def" "b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategyDetail/Component_listContextMenuMatAttrSettingAndPlanStrategyDetail\0431.def"
new file mode 100644
index 0000000..a829c7d
--- /dev/null
+++ "b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategyDetail/Component_listContextMenuMatAttrSettingAndPlanStrategyDetail\0431.def"
@@ -0,0 +1,10 @@
+Quintiq file version 2.0
+Component listContextMenuMatAttrSettingAndPlanStrategyDetail id:listContextMenuMatAttrSettingAndPlanStrategyDetail_1
+{
+  #keys: '[414384.0.769370490]'
+  BaseType: 'listContextMenu'
+  Properties:
+  [
+    Taborder: 0
+  ]
+}
diff --git a/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategyDetail/_ROOT_Component_FormMatAttrSettingAndPlanStrategyDetail.def b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategyDetail/_ROOT_Component_FormMatAttrSettingAndPlanStrategyDetail.def
new file mode 100644
index 0000000..5247d29
--- /dev/null
+++ b/_Main/UI/MacroPlannerWebApp/Component_FormMatAttrSettingAndPlanStrategyDetail/_ROOT_Component_FormMatAttrSettingAndPlanStrategyDetail.def
@@ -0,0 +1,17 @@
+Quintiq file version 2.0
+#root
+#parent: MacroPlannerWebApp
+OrphanComponent FormMatAttrSettingAndPlanStrategyDetail
+{
+  #keys: '[414384.0.769370336]'
+  BaseType: 'WebForm'
+  Children:
+  [
+    #child: ListMatAttrSettingAndPlanStrategyDetail_21
+  ]
+  Properties:
+  [
+    Description: '鐗╂枡灞炴�ф爣绛捐瀹�&鐗╂枡璁″垝绛栫暐'
+    Title: '鐗╂枡鍏宠仈浜у搧'
+  ]
+}

--
Gitblit v1.9.3