Quintiq file version 2.0 
 | 
#parent: #root 
 | 
StaticMethod RefreshOfflinePlan ( 
 | 
  MacroPlan macroPlan 
 | 
) 
 | 
{ 
 | 
  TextBody: 
 | 
  [* 
 | 
    macroPlan.NewOfflinePlanTable( relflush ); 
 | 
     
 | 
    nopt         := macroPlan.NewOfflinePlanTable( relnew, SaveDateTime := DateTime::ActualTime() ); 
 | 
     
 | 
    // 计划开始时间 
 | 
    planningDate := macroPlan.StartOfPlanning().Date()  
 | 
     
 | 
    // 初始化下线计划列 
 | 
    traverse ( macroPlan, Period_MP, pmp, pmp.IsPlanning() and not pmp.IsHistorical() ) { 
 | 
      nopt.NewOfflinePlanColumn( relnew, StartDate := pmp.StartDate(), EndDate := pmp.EndDate() ); 
 | 
    } 
 | 
     
 | 
    // 生成下线计划表【一条产线在同一天不会产生两次相同产品的周期任务】 
 | 
    traverse ( macroPlan, Unit, u, u.HasCapacityTypeTime()  
 | 
    //           and u.Name() = "eMotor Assy (France)" // 测试本地场景时可以过滤 
 | 
    //           and u.Name() = "DL-MoMo"              // 测试实际场景时可以过滤 
 | 
              )  
 | 
    { 
 | 
      // 循环遍历周期任务的NewSupply【生成明细下线计划】 
 | 
      traverse ( u, Operation, o ) { 
 | 
        traverse ( o, PeriodTaskOperation.NewSupply, ns ) { 
 | 
          // ProductInStockingPoint_MP 
 | 
          pisp     := ns.AsProductionSupply().ProductInStockingPoint_MP(); 
 | 
          // ProductInStockingPointInPeriodPlanningLeaf 
 | 
          pispippl := ns.ProductInStockingPointInPeriodPlanningLeaf(); 
 | 
          // Period_MP 
 | 
          pmp      := pispippl.Period_MP(); 
 | 
          // ShiftPattern 
 | 
          sp       := ns.PeriodTask_MP().UnitPeriod().astype( UnitPeriodTimeBase ).ShiftPattern(); 
 | 
          // ShiftDayTime 
 | 
          sdt      := select( sp, ShiftDayTime, tempSDT, tempSDT.Name() = tempSDT.ShiftPattern().Name() ); 
 | 
           
 | 
          // 生成下线计划【产线明细】行 
 | 
          detailedNOPR   := select( nopt, NewOfflinePlanRow, tempNOPR, tempNOPR.ProductionLine() = u.ID() and tempNOPR.ProductID() = pisp.ProductID() and tempNOPR.StockingPointID() = pisp.StockingPointID() and tempNOPR.Type() = "1" ); 
 | 
          if ( isnull( detailedNOPR ) ) { 
 | 
            detailedNOPR := nopt.NewOfflinePlanRow( relnew, ProductionLine := u.ID(), ProductID := pisp.ProductID(),StockingPointID := pisp.StockingPointID(), Type := "1", OperationID := o.ID() ); 
 | 
          } 
 | 
           
 | 
          // 生成下线计划列 
 | 
          nopc   := select( nopt, NewOfflinePlanColumn, tempNOPC, tempNOPC.StartDate() = pmp.StartDate() and tempNOPC.EndDate() = pmp.EndDate() ); 
 | 
          if ( isnull( nopc ) ) { 
 | 
            nopc := nopt.NewOfflinePlanColumn( relnew, StartDate := pmp.StartDate(), EndDate := pmp.EndDate() ); 
 | 
          } 
 | 
           
 | 
          // 生成下线计划【产线明细】单元格 
 | 
          detaileNOPCell := select( detailedNOPR, NewOfflinePlanCell, tempNOPCell, tempNOPCell.NewOfflinePlanColumn() = nopc ); 
 | 
          if ( isnull ( detaileNOPCell ) ) { 
 | 
            detaileNOPCell := detailedNOPR.NewOfflinePlanCell( relnew,  
 | 
                                                               Quantity          := ns.Quantity().Round( 0 ),  
 | 
                                                               InventoryWeight   := pispippl.InventoryLevelEnd() - pispippl.MinInventoryLevel(), 
 | 
                                                               ShiftPatternName  := guard( sp.Name(), "" ), 
 | 
                                                               ShiftPatternStart := guard( sdt.StartDateTime().Format( "H:m" ), "" ), 
 | 
                                                               ShiftPatternEnd   := guard( sdt.EndDateTIme().Format( "H:m" ), "" ) ); 
 | 
            detaileNOPCell.NewOfflinePlanColumn( relset, nopc ); 
 | 
          } 
 | 
        } 
 | 
      } 
 | 
       
 | 
      // 补齐空格子 
 | 
      traverse ( nopt, NewOfflinePlanRow, nopr ) { 
 | 
        traverse ( nopt, NewOfflinePlanColumn, nopc ) { 
 | 
          cell   := select( nopr, NewOfflinePlanCell, tempNOPCell, tempNOPCell.NewOfflinePlanColumn() = nopc ); 
 | 
          if ( isnull( cell ) ) { 
 | 
            uptb := select( macroPlan, Unit.UnitPeriod.astype( UnitPeriodTimeBase ), tempUPTB,  
 | 
                            tempUPTB.UnitID() = nopr.ProductionLine() and tempUPTB.StartDate() = nopc.StartDate() and tempUPTB.End().Date() = nopc.EndDate() ); 
 | 
            // ShiftPattern 
 | 
            sp   := uptb.ShiftPattern(); 
 | 
            // ShiftDayTime 
 | 
            sdt  := select( sp, ShiftDayTime, tempSDT, tempSDT.Name() = tempSDT.ShiftPattern().Name() ); 
 | 
            cell := nopr.NewOfflinePlanCell( relnew,  
 | 
                                             ShiftPatternName  := guard( sp.Name(), "" ),  
 | 
                                             ShiftPatternStart := guard( sdt.StartDateTime().Format( "H:m" ), "" ), 
 | 
                                             ShiftPatternEnd   := guard( sdt.EndDateTIme().Format( "H:m" ), "" ) ); 
 | 
            cell.NewOfflinePlanColumn( relset, nopc ); 
 | 
          } 
 | 
        } 
 | 
      } 
 | 
       
 | 
      // 【生成合计下线计划】 
 | 
      totalNOPR   := nopt.NewOfflinePlanRow( relnew, ProductID := "All", ProductionLine := u.ID(), Type := "2" ); 
 | 
      detailNOPRs := selectset( nopt, NewOfflinePlanRow, tempNOPR, tempNOPR.ProductionLine() = u.ID() and tempNOPR.Type() = "1" ); 
 | 
      traverse ( detailNOPRs, Elements, detailNOPR ) { 
 | 
        traverse ( detailNOPR, NewOfflinePlanCell, detailNOPCell ) { 
 | 
          // 生产下线计划【产线合计】单元格 
 | 
          totalNOPRCell   := select( totalNOPR, NewOfflinePlanCell, tempNOPCell, tempNOPCell.NewOfflinePlanColumn() = detailNOPCell.NewOfflinePlanColumn() ); 
 | 
          if ( isnull( totalNOPRCell ) ) { 
 | 
            totalNOPRCell := totalNOPR.NewOfflinePlanCell( relnew,  
 | 
                                                           ShiftPatternName  := detailNOPCell.ShiftPatternName(), 
 | 
                                                           ShiftPatternStart := detailNOPCell.ShiftPatternStart(), 
 | 
                                                           ShiftPatternEnd   := detailNOPCell.ShiftPatternEnd() ); 
 | 
            totalNOPRCell.NewOfflinePlanColumn( relset, detailNOPCell.NewOfflinePlanColumn() ); // 设置列 
 | 
            // 将明细单元格关联到合计单元格 
 | 
            totalNOPRCell.Detailed( relinsert, detailNOPCell ); 
 | 
          } else { 
 | 
            // 将明细单元格关联到合计单元格 
 | 
            totalNOPRCell.Detailed( relinsert, detailNOPCell ); 
 | 
          } 
 | 
        } 
 | 
      } 
 | 
       
 | 
      // 设置生产顺序【对下线计划明细生效】 
 | 
      indexColumn    := select( nopt, NewOfflinePlanColumn, tempNOPC, tempNOPC.StartDate() = planningDate ); 
 | 
      previousColumn := indexColumn.PreviousNOPColumn(); 
 | 
      nextColumn     := indexColumn.NextNOPColumn(); 
 | 
      while ( not isnull( indexColumn.NextNOPColumn() ) 
 | 
    //          and indexColumn.ColumnDate() <= Date::Construct( 2020, 4, 1 ) // 测试实际场景时可以过滤 
 | 
             )  
 | 
      { 
 | 
        orderNr     := 1; 
 | 
        nopcells    := selectsortedset( indexColumn, NewOfflinePlanCell, tempNOPCell, tempNOPCell.FindProductionLineAndType( u.ID(), "1" ), tempNOPCell.InventoryWeight() ); 
 | 
        initialSize := nopcells.Size(); 
 | 
    //    info( "计划开始时间:", planningDate.Format( "Y-M2-D2" ), "    索引时间:", indexColumn.StartDate().Format( "Y-M2-D2" ), "    个数:", nopcells.Size() ); 
 | 
         
 | 
        if ( nopcells.Size() > 0 ) { 
 | 
         
 | 
          // 判定1 
 | 
          previousOPCell := maxselect( previousColumn, NewOfflinePlanCell, tempNOPCell, tempNOPCell.FindProductionLineAndType( u.ID(), "1" ), tempNOPCell.OrderNr() ); 
 | 
          if ( isnull( previousOPCell ) or indexColumn.StartDate() = planningDate ) { 
 | 
            nopcell := nopcells.Element( 0 ); 
 | 
            nopcell.Order( "#" + orderNr.Format( "N(LPad0(2))" ) ); 
 | 
            nopcell.OrderNr( orderNr ); 
 | 
            orderNr++; 
 | 
            nopcells.Remove( nopcell ); 
 | 
          } else { 
 | 
            nopcell := select( nopcells, Elements, tempNOPCell, tempNOPCell.NewOfflinePlanRow().ProductID() =  previousOPCell.NewOfflinePlanRow().ProductID() ); 
 | 
            if ( not isnull( nopcell ) ) { 
 | 
              nopcell.Order( "#" + orderNr.Format( "N(LPad0(2))" ) ); 
 | 
              nopcell.OrderNr( orderNr ); 
 | 
              orderNr++; 
 | 
              nopcells.Remove( nopcell ); 
 | 
            } 
 | 
          } 
 | 
           
 | 
          // 判定2 
 | 
          nextNOPCells := selectset( nopcells, Elements, tempOPC, 
 | 
                                     exists( nextColumn, NewOfflinePlanCell, nextOPCell, nextOPCell.FindProductionLineAndType( u.ID(), "1" ) and  
 | 
                                             nextOPCell.NewOfflinePlanRow().ProductID() = tempOPC.NewOfflinePlanRow().ProductID() ) ); // 找下一列是否有当前列生产的产品 
 | 
          if ( nextNOPCells.Size() = 1 ) { 
 | 
            nopcell := nextNOPCells.Element( 0 ); 
 | 
            nopcell.Order( "#" + initialSize.Format( "N(LPad0(2))" ) ); 
 | 
            nopcell.OrderNr( initialSize ); 
 | 
            nopcells.Remove( nopcell ); 
 | 
          } 
 | 
           
 | 
          // 判定3 
 | 
          traverse ( nopcells, Elements, opcell ) { 
 | 
            opcell.Order( "#" + orderNr.Format( "N(LPad0(2))" ) ); 
 | 
            opcell.OrderNr( orderNr ); 
 | 
            orderNr++; 
 | 
            nopcells.Remove( opcell ); 
 | 
          } 
 | 
        } 
 | 
         
 | 
        indexColumn    := indexColumn.NextNOPColumn(); 
 | 
        previousColumn := indexColumn.PreviousNOPColumn(); 
 | 
        nextColumn     := indexColumn.NextNOPColumn(); 
 | 
      } 
 | 
    } 
 | 
  *] 
 | 
} 
 |