| Quintiq file version 2.0 | 
| #parent: #root | 
| Method MappingOperationBOMDataRouting ( | 
|   Routing routing, | 
|   GlobalOTDTable globalOTDTable, | 
|   Global_MappingOperationBOMs routingRows | 
| ) | 
| { | 
|   TextBody: | 
|   [* | 
|     // yypsybs Aug-21-2023 (created) | 
|      | 
|     // 根据工艺段汇总处理 | 
|     processSections := selectuniquevalues( routingRows, Elements, row, true, row.ProcessSection() ); | 
|     traverse( processSections, Elements, processSection ) { | 
|         rows := selectset( routingRows, Elements, row, row.ProcessSection() = processSection ); | 
|         firstRow := rows.Element( 0 ); | 
|         // 找orgCode/productId/processSection匹配且sequence最小的一组数据 | 
|         minSeq := Global_MappingOperation::FindMinSeq( globalOTDTable, firstRow.OrganCode(), firstRow.ProductCode(), processSection ); | 
|         routingStepId := processSection + "_" + [String]minSeq; | 
|         // 找对应routingStep | 
|         routingStep := RoutingStep::FindByName( routing, routingStepId ); | 
|         if( not isnull( routingStep ) ) { | 
|     //        error( "routing step : " + routing.ID() + "|" + routingStepId + " not found" );   | 
|         // 仅主料,统一处理 | 
|           noAlterRows := selectset( rows, Elements, noAlterRow, noAlterRow.AlternativeMaterialCode() = "" ); | 
|           traverse( noAlterRows, Elements, noAlterRow ) { | 
|               traverse( routingStep, Operation, toLink ) { | 
|                   // 检查主料 | 
|                   component := Product_MP::FindById( this, noAlterRow.ComponentCode() ); | 
|                   if( not isnull( component ) ) { | 
|     //                  error( "component : " + noAlterRow.ComponentCode() + " not found" ); | 
|                   // 连接产品与operation | 
|     //              inputStockingPointId := noAlterRow.OrganCode()  + "_" + noAlterRow.ComponentType() + "_Stock"; | 
|                   inputStockingPointId := noAlterRow.OrganCode() + "_Stock"; | 
|                   stockingPoint := StockingPoint_MP::FindStockingPointTypeIndex( inputStockingPointId); | 
|                   pisp := ProductInStockingPoint_MP::CreateIfNotFound( component, stockingPoint ); | 
|                   trash := construct( OperationBOMs ); | 
|                   operationBOM := toLink.LinkProduct( component, true, BaseOperationLink::GetGroupID( toLink, true, false ), pisp,  | 
|                                                       true, trash ); | 
|                   operationBOM.MinQuantityInGroup( 0 ); | 
|                   operationBOM.Quantity( noAlterRow.UnitUsageOfComponents() / noAlterRow.ComponentOutputRate() ); | 
|                   operationBOM.MaxQuantityInGroup( noAlterRow.UnitUsageOfComponents() / noAlterRow.ComponentOutputRate() ); | 
|                   } | 
|               } | 
|           } | 
|           // 替换料,按主料分组处理 | 
|           alterComponentIds := selectuniquevalues( rows, Elements, row, row.AlternativeMaterialCode() <> "", row.ComponentCode() ); | 
|           traverse( alterComponentIds, Elements, alterComponentId ) { | 
|               alterRows := selectset( rows, Elements, row, row.ComponentCode() = alterComponentId ); | 
|               firstAlterRow := alterRows.Element( 0 ); | 
|               // 检查主料 | 
|               component := Product_MP::FindById( this, firstAlterRow.ComponentCode() ); | 
|               if( not isnull( component ) ) { | 
|     //              error( "component : " + firstAlterRow.ComponentCode() + " not found" ); | 
|     //          } | 
|                 traverse( routingStep, Operation, toLink ) { | 
|                     // 连接产品与operation | 
|     //                inputStockingPointId := firstAlterRow.OrganCode()  + "_" + firstAlterRow.ComponentType() + "_Stock"; | 
|                     inputStockingPointId := firstAlterRow.OrganCode() + "_Stock"; | 
|                     stockingPoint := StockingPoint_MP::FindStockingPointTypeIndex( inputStockingPointId); | 
|                     pisp := ProductInStockingPoint_MP::CreateIfNotFound( component, stockingPoint ); | 
|                     trash := construct( OperationBOMs ); | 
|                     mainBOM := toLink.LinkProduct( component, true, BaseOperationLink::GetGroupID( toLink, true, false ), pisp,  | 
|                                                         true, trash ); | 
|                     mainBOM.Quantity( firstAlterRow.UnitUsageOfComponents() / firstAlterRow.ComponentOutputRate() ); | 
|                     mainBOM.MaxQuantityInGroup( firstAlterRow.UnitUsageOfComponents() / firstAlterRow.ComponentOutputRate() ); | 
|                     mainQty := mainBOM.Quantity(); | 
|                     Transaction::Transaction().Propagate(); | 
|                     // 添加辅料 | 
|                     traverse( alterRows, Elements, alterRow ) { | 
|                         alterProd := Product_MP::FindById( this, alterRow.AlternativeMaterialCode() ); | 
|                         if( not isnull( alterProd ) ) { | 
|         //                    error( "alterProd : " + alterRow.AlternativeMaterialCode() + " not found" ); | 
|     //                      stockingPointIdAlter := alterRow.OrganCode()  + "_" + alterRow.ComponentType() + "_Stock"; | 
|                           stockingPointIdAlter := alterRow.OrganCode() + "_Stock"; | 
|                           stockingPointAlter := StockingPoint_MP::FindById( this, stockingPointIdAlter ); | 
|                           if( isnull( stockingPointAlter ) ) { | 
|                               error( "stockingPoint : " + stockingPointIdAlter + " not found" ); | 
|                           } | 
|                           pispAlter := ProductInStockingPoint_MP::CreateIfNotFound( alterProd, stockingPointAlter ); | 
|                           //mainInput := toLink.LastOperationInput();  | 
|                           mainInput := select( toLink,OperationInput,operationInut,operationInut.ProductID()=alterRow.ComponentCode()); | 
|                           trash := construct( OperationBOMs ); | 
|                           if( not isnull( mainInput ) ) { | 
|                               alterBom := mainInput.Operation().LinkPISP( pispAlter, true, mainInput.OperationLinkGroupID(), trash ); | 
|                               alterBom.Quantity( mainBOM.MaxQuantityInGroup() * alterRow.AlternativeRate() ); | 
|                               alterBom.MaxQuantityInGroup( mainBOM.MaxQuantityInGroup() ); | 
|     //                          info( "Quantity" + [String]alterBom.Quantity() ) | 
|     //                          info( "MaxQuantityInGroup" + [String]alterBom.MaxQuantityInGroup() ) | 
|                               mainQty := mainQty - alterBom.Quantity(); | 
|                           } | 
|                       } | 
|                       mainBOM.Quantity( mainQty ); | 
|                    } | 
|                 } | 
|               } | 
|           } | 
|        } | 
|     } | 
|   *] | 
| } |