From 2080f2378f836d1ea8b79b8d2e3fca0665d27e1c Mon Sep 17 00:00:00 2001
From: hongji.li <hongji.a.li@capgemini.com>
Date: 星期二, 26 九月 2023 08:51:34 +0800
Subject: [PATCH] Merge branch 'feature/kevin_addsanitycheck' into dev

---
 _Main/BL/Type_Global_MappingProduct_MP/Method_SetIsLinkedWithFinishedGoodAttributes_Recursive.qbl |   83 ++++++++++++++++++++
 /dev/null                                                                                         |   38 ---------
 _Main/BL/Type_Global_MappingOperation/Attribute_IsLinkedWithFinishedGood.qbl                      |    8 ++
 _Main/BL/Type_Global_MappingOperationBOM/Attribute_IsLinkedWithFinishedGood.qbl                   |    8 ++
 _Main/BL/Type_GlobalDTOTable/Method_SetIsLinkedWithFinishedGoodAttributes.qbl                     |   41 ++++++++++
 _Main/BL/Type_Global_MappingProduct_MP/Attribute_IsLinkedWithFinishedGood.qbl                     |    8 ++
 _Main/BL/Type_Routing/Method_DoSanityCheckData.qbl                                                |   20 +++++
 _Main/BL/Type_Routing/Method_GetHasTianmaNonSupplierOperationWithNoInput.qbl                      |   28 +++++++
 8 files changed, 196 insertions(+), 38 deletions(-)

diff --git a/_Main/BL/Type_GlobalDTOTable/Method_SetIsLinkedWithFinishedGoodAttributes.qbl b/_Main/BL/Type_GlobalDTOTable/Method_SetIsLinkedWithFinishedGoodAttributes.qbl
new file mode 100644
index 0000000..6aedc24
--- /dev/null
+++ b/_Main/BL/Type_GlobalDTOTable/Method_SetIsLinkedWithFinishedGoodAttributes.qbl
@@ -0,0 +1,41 @@
+Quintiq file version 2.0
+#parent: #root
+Method SetIsLinkedWithFinishedGoodAttributes
+{
+  Description: 'Method to traverse the supply chain to determine if there are any products that are not used to produce finished goods.'
+  TextBody:
+  [*
+    // Reset IsLinkedWithFinishedGood
+    traverse( this, Global_MappingProduct_MP, instance )
+    {
+      instance.IsLinkedWithFinishedGood( false );
+    }
+    
+    traverse( this, Global_MappingOperation, instance )
+    {
+      instance.IsLinkedWithFinishedGood( false );
+    }
+    
+    traverse( this, Global_MappingOperationBOM, instance )
+    {
+      instance.IsLinkedWithFinishedGood( false );
+    }
+    
+    productspool := selectset( this, Global_MappingProduct_MP, product,
+                               product.ProductMajorType() <> "鎴愬搧" );
+    operationspool := this.Global_MappingOperation( relget );
+    operationbomspool := this.Global_MappingOperationBOM( relget );
+    
+    // Traverse each finished good and search for linked products/operations/lanes
+    traverse( this, Global_MappingProduct_MP, product,
+              product.ProductMajorType() = "鎴愬搧" )
+    {
+      product.SetIsLinkedWithFinishedGoodAttributes_Recursive( 0, // depth
+                                                               100, // maxdepth
+                                                               productspool,
+                                                               operationspool,
+                                                               operationbomspool );
+      
+    }
+  *]
+}
diff --git a/_Main/BL/Type_Global_MappingOperation/Attribute_IsLinkedWithFinishedGood.qbl b/_Main/BL/Type_Global_MappingOperation/Attribute_IsLinkedWithFinishedGood.qbl
new file mode 100644
index 0000000..76d65ba
--- /dev/null
+++ b/_Main/BL/Type_Global_MappingOperation/Attribute_IsLinkedWithFinishedGood.qbl
@@ -0,0 +1,8 @@
+Quintiq file version 2.0
+#parent: #root
+Attribute IsLinkedWithFinishedGood
+{
+  #keys: '3[157968.0.1145180207][157968.0.1145180206][157968.0.1145180208]'
+  Description: 'Updated procedurally for checking whether this object is used to produce a finished good.'
+  ValueType: Boolean
+}
diff --git a/_Main/BL/Type_Global_MappingOperationBOM/Attribute_IsLinkedWithFinishedGood.qbl b/_Main/BL/Type_Global_MappingOperationBOM/Attribute_IsLinkedWithFinishedGood.qbl
new file mode 100644
index 0000000..e5ff163
--- /dev/null
+++ b/_Main/BL/Type_Global_MappingOperationBOM/Attribute_IsLinkedWithFinishedGood.qbl
@@ -0,0 +1,8 @@
+Quintiq file version 2.0
+#parent: #root
+Attribute IsLinkedWithFinishedGood
+{
+  #keys: '3[157968.0.1145180190][157968.0.1145180189][157968.0.1145180191]'
+  Description: 'Updated procedurally for checking whether this object is used to produce a finished good.'
+  ValueType: Boolean
+}
diff --git a/_Main/BL/Type_Global_MappingProduct_MP/Attribute_IsLinkedWithFinishedGood.qbl b/_Main/BL/Type_Global_MappingProduct_MP/Attribute_IsLinkedWithFinishedGood.qbl
new file mode 100644
index 0000000..d2cec36
--- /dev/null
+++ b/_Main/BL/Type_Global_MappingProduct_MP/Attribute_IsLinkedWithFinishedGood.qbl
@@ -0,0 +1,8 @@
+Quintiq file version 2.0
+#parent: #root
+Attribute IsLinkedWithFinishedGood
+{
+  #keys: '3[157968.0.1145180168][157968.0.1145180167][157968.0.1145180169]'
+  Description: 'Updated procedurally for checking whether this product is used to produce a finished good.'
+  ValueType: Boolean
+}
diff --git a/_Main/BL/Type_Global_MappingProduct_MP/Method_SetIsLinkedWithFinishedGoodAttributes_Recursive.qbl b/_Main/BL/Type_Global_MappingProduct_MP/Method_SetIsLinkedWithFinishedGoodAttributes_Recursive.qbl
new file mode 100644
index 0000000..4c9b813
--- /dev/null
+++ b/_Main/BL/Type_Global_MappingProduct_MP/Method_SetIsLinkedWithFinishedGoodAttributes_Recursive.qbl
@@ -0,0 +1,83 @@
+Quintiq file version 2.0
+#parent: #root
+Method SetIsLinkedWithFinishedGoodAttributes_Recursive (
+  Number depth,
+  Number maxdepth,
+  Global_MappingProduct_MPs productspool,
+  Global_MappingOperations operationspool,
+  Global_MappingOperationBOMs operationbomspool
+)
+{
+  Description: 'Method to traverse the supply chain recursively to determine if there are any products that are not used to produce finished goods.'
+  TextBody:
+  [*
+    if( not this.IsLinkedWithFinishedGood() )
+    {
+      depth := depth + 1;
+      this.IsLinkedWithFinishedGood( true );
+      
+      if( depth <= maxdepth )
+      {
+        operations := selectset( operationspool, Elements, operation,
+                                 not operation.IsLinkedWithFinishedGood()
+                                 and operation.BusinessType() = this.BusinessType()
+                                 and operation.ProductID() = this.ID() );
+        operationspool.Remove( operations );
+        
+        traverse( operations, Elements, operation )
+        {
+          operation.IsLinkedWithFinishedGood( true );
+          
+          operationboms := selectset( operationbomspool, Elements, operationbom,
+                                      not operationbom.IsLinkedWithFinishedGood()
+                                      and operationbom.BusinessType() = operation.BusinessType()
+                                      and operationbom.OrganCode() = operation.OrganCode()
+                                      and operationbom.ProcessSection() = operation.ProcessSection()
+                                      and operationbom.ProductCode() = operation.ProductID() );
+          operationbomspool.Remove( operationboms );
+          
+          traverse( operationboms, Elements, operationbom )
+          {
+            operationbom.IsLinkedWithFinishedGood( true );
+            
+            componentproduct := Global_MappingProduct_MP::FindTypeIndexIDAndBusinessType( operationbom.ComponentCode(),
+                                                                                          operationbom.BusinessType() );
+            
+            if( guard( not componentproduct.IsLinkedWithFinishedGood(), false ) )
+            {
+              productspool.Remove( componentproduct );
+              componentproduct.SetIsLinkedWithFinishedGoodAttributes_Recursive( depth,
+                                                                                maxdepth,
+                                                                                productspool,
+                                                                                operationspool,
+                                                                                operationbomspool );
+            }
+            
+            if( operationbom.AlternativeMaterialCode() <> ""
+                and operationbom.AlternativeMaterialCode() <> operationbom.ComponentCode() )
+            {
+              alternativeproduct := Global_MappingProduct_MP::FindTypeIndexIDAndBusinessType( operationbom.AlternativeMaterialCode(),
+                                                                                              operationbom.BusinessType() );
+              
+              if( guard( not alternativeproduct.IsLinkedWithFinishedGood(), false ) )
+              {
+                productspool.Remove( alternativeproduct );
+                alternativeproduct.SetIsLinkedWithFinishedGoodAttributes_Recursive( depth,
+                                                                                    maxdepth,
+                                                                                    productspool,
+                                                                                    operationspool,
+                                                                                    operationbomspool );
+              }
+            }
+          }
+        }
+      }
+      else
+      {
+        debuginfo( "Product:", this.ID(),
+                   "| BusinessType:", this.BusinessType(),
+                   "| Max depth reached, stop searching... (", depth, ")" );
+      }
+    }
+  *]
+}
diff --git a/_Main/BL/Type_Operation/Method_GetHasValidOperationInputOutput.qbl b/_Main/BL/Type_Operation/Method_GetHasValidOperationInputOutput.qbl
deleted file mode 100644
index 09ae8ea..0000000
--- a/_Main/BL/Type_Operation/Method_GetHasValidOperationInputOutput.qbl
+++ /dev/null
@@ -1,38 +0,0 @@
-Quintiq file version 2.0
-#parent: #root
-Method GetHasValidOperationInputOutput (
-  output Strings feedback_o,
-  output Strings sanitycheckfeedback_o
-) declarative remote #extension
-{
-  TextBody:
-  [*
-    // desmondt Oct-3-2014 (created)
-    feedback := '';
-    sanitycheckfeedback := ''
-    
-    if( ( this.Unit().QuantityToProcess() = GlobalParameters_MP::GetQTProcessIn()
-          or not this.Unit().IsSupplier() ) // Tianma change 20230925: If the unit is not a supplier, raise a data issue if there's no input
-        and this.OperationInput( relsize ) = 0 )
-    {
-      feedback := Translations::MP_Operation_ViolateHasValidOperationInputOutput_NoOperationInput();
-      sanitycheckfeedback_o.Add( SanityCheckCategoryLevel::GetSanityCheckCategoryDataIssue() );
-    }
-    else if( this.Unit().QuantityToProcess() = GlobalParameters_MP::GetQTProcessOut()
-             and this.OperationOutput( relsize ) = 0 )
-    {
-      feedback := Translations::MP_Operation_ViolateHasValidOperationInputOutput_NoOperationOutput();
-      sanitycheckfeedback := SanityCheckCategoryLevel::GetSanityCheckCategoryDataIssue();
-    }
-    
-    if( not isnull( feedback_o ) and feedback <> '' )
-    {
-      name := MacroPlan::GetSubstituteName( this.Name() ); // To avoid empty name/name too long
-      feedback_o.Add( SanityCheckMessage::GetFormattedMessage( Translations::MP_Process_Instance( this.DefinitionName(), name ),
-                                                               feedback ) );
-      sanitycheckfeedback_o.Add( sanitycheckfeedback );
-    }
-    
-    return feedback = '';
-  *]
-}
diff --git a/_Main/BL/Type_Routing/Method_DoSanityCheckData.qbl b/_Main/BL/Type_Routing/Method_DoSanityCheckData.qbl
new file mode 100644
index 0000000..c23a63b
--- /dev/null
+++ b/_Main/BL/Type_Routing/Method_DoSanityCheckData.qbl
@@ -0,0 +1,20 @@
+Quintiq file version 2.0
+#parent: #root
+Method DoSanityCheckData (
+  output Strings feedback_o,
+  output Strings sanitycheckfeedback_o
+) declarative remote #extension
+{
+  TextBody:
+  [*
+    // Adhi Feb-10-2016 (created)
+    
+    isvalid := true;
+    
+    isvalid := this.GetHasValidInput( feedback_o, sanitycheckfeedback_o ) and isvalid;
+    
+    isvalid := this.GetHasTianmaNonSupplierOperationWithNoInput( feedback_o, sanitycheckfeedback_o ) and isvalid;
+    
+    return isvalid;
+  *]
+}
diff --git a/_Main/BL/Type_Routing/Method_GetHasTianmaNonSupplierOperationWithNoInput.qbl b/_Main/BL/Type_Routing/Method_GetHasTianmaNonSupplierOperationWithNoInput.qbl
new file mode 100644
index 0000000..ec4ca3e
--- /dev/null
+++ b/_Main/BL/Type_Routing/Method_GetHasTianmaNonSupplierOperationWithNoInput.qbl
@@ -0,0 +1,28 @@
+Quintiq file version 2.0
+#parent: #root
+Method GetHasTianmaNonSupplierOperationWithNoInput (
+  output Strings feedback_o,
+  output Strings sanitycheckfeedback_o
+) declarative remote as Boolean
+{
+  TextBody:
+  [*
+    // Tianma change 20230925: If the unit is not a supplier, raise a data issue if there's no input
+    value := forall( this, RoutingStep.Operation, operation,
+                     guard( operation.Unit().IsSupplier(), false )
+                     or operation.OperationInput( relsize ) > 0 );
+    
+    if( not value )
+    {
+      // Add instance text
+      routingname := MacroPlan::GetSubstituteName( this.Name() );
+      instance := Translations::MP_Routing_Instance( routingname );
+      feedback := SanityCheckMessage::GetFormattedMessage( instance,
+                                                           "闈炰緵搴斿晢鎿嶄綔娌℃湁鎶曞叆鏂欍��" );
+      feedback_o.Add( feedback );
+      sanitycheckfeedback_o.Add( SanityCheckCategoryLevel::GetSanityCheckCategoryDataWarning() );
+    }
+    
+    return value;
+  *]
+}

--
Gitblit v1.9.3