Quintiq file version 2.0 
 | 
#parent: #root 
 | 
StaticMethod RefreshOfflinePlan ( 
 | 
  MacroPlan macroPlan 
 | 
) 
 | 
{ 
 | 
  TextBody: 
 | 
  [* 
 | 
    macroPlan.OfflinePlanTable( relflush ); 
 | 
     
 | 
    opt := macroPlan.OfflinePlanTable( relnew, SaveDateTime := DateTime::ActualTime() ); 
 | 
     
 | 
    // 生成下线计划表 
 | 
    traverse ( macroPlan, Unit, u, u.HasCapacityTypeTime() /*and u.Name() = "Body in White Line 1"*/ ) { 
 | 
      // 创建产线行 
 | 
      opt.OfflinePlanRow( relnew, ProductionLine := u.ID(), ProductID := "", Type := "0" ); 
 | 
       
 | 
      traverse ( u, Operation, o ) { 
 | 
        traverse ( o, PeriodTaskOperation.NewSupply, ns ) { 
 | 
          // 找行 
 | 
          oprQuantity := select( opt, OfflinePlanRow, tempOPR, tempOPR.ProductionLine() = u.ID() and tempOPR.ProductID() = ns.AsProductionSupply().ProductInStockingPoint_MP().ProductID() and tempOPR.Type() = "1" ); 
 | 
          oprOrder    := select( opt, OfflinePlanRow, tempOPR, tempOPR.ProductionLine() = u.ID() and tempOPR.ProductID() = ns.AsProductionSupply().ProductInStockingPoint_MP().ProductID() and tempOPR.Type() = "2" ); 
 | 
          if ( isnull( oprQuantity ) and isnull( oprOrder ) ) { 
 | 
            oprQuantity := opt.OfflinePlanRow( relnew, ProductionLine := u.ID(), ProductID := ns.AsProductionSupply().ProductInStockingPoint_MP().ProductID(), Type := "1", Notes := ns.AsProductionSupply().ProductInStockingPoint_MP().Product_MP().Notes() ); 
 | 
            oprOrder    := opt.OfflinePlanRow( relnew, ProductionLine := u.ID(), ProductID := ns.AsProductionSupply().ProductInStockingPoint_MP().ProductID(), Type := "2" ); 
 | 
          } 
 | 
           
 | 
          // 找列 
 | 
          opc := select( opt, OfflinePlanColumn, tempOPC, tempOPC.ColumnDate() = ns.Start().Date() ); 
 | 
          if ( isnull( opc ) ) { 
 | 
            opc := opt.OfflinePlanColumn( relnew, ColumnDate := ns.Start().Date() ); 
 | 
          } 
 | 
           
 | 
          // 赋值单元格 
 | 
          cellQuantity := opc.OfflinePlanCell( relnew, Value := [String]ns.Quantity().Round( 0 ), Shift := ns.PeriodTask_MP().UnitPeriod().astype( UnitPeriodTimeBase ).ShiftPattern().Name(), Quantity := ns.Quantity() ); 
 | 
          cellQuantity.OfflinePlanRow( relset, oprQuantity ); 
 | 
          cellOrder := opc.OfflinePlanCell( relnew, Value := "单号" + [String]ns.Quantity().Round( 0 ) + "_" + [String]( ns.ProductInStockingPointInPeriodPlanningLeaf().InventoryLevelEnd() - ns.ProductInStockingPointInPeriodPlanningLeaf().MinInventoryLevel() ),  
 | 
                                            Quantity := ns.Quantity(),  
 | 
                                            InventoryWeight := ns.ProductInStockingPointInPeriodPlanningLeaf().InventoryLevelEnd() - ns.ProductInStockingPointInPeriodPlanningLeaf().MinInventoryLevel() ); 
 | 
          cellOrder.OfflinePlanRow( relset, oprOrder ); 
 | 
        } 
 | 
      } 
 | 
       
 | 
      // 创建总量行 
 | 
      opt.OfflinePlanRow( relnew, ProductionLine := u.ID(), ProductID := "Z", Type := "3" ); 
 | 
      // 创建班次行 
 | 
      opt.OfflinePlanRow( relnew, ProductionLine := u.ID(), ProductID := "Z", Type := "4" ); 
 | 
      // 创建班次开始时间行 
 | 
      opt.OfflinePlanRow( relnew, ProductionLine := u.ID(), ProductID := "Z", Type := "5" ); 
 | 
      // 创建班次结束时间行 
 | 
      opt.OfflinePlanRow( relnew, ProductionLine := u.ID(), ProductID := "Z", Type := "6" ); 
 | 
    } 
 | 
     
 | 
    // 创建产品列&类型列 
 | 
    productOPC := opt.OfflinePlanColumn( relnew, ColumnDate := macroPlan.StartOfPlanning().Date() - 2 ); 
 | 
    typeOPC    := opt.OfflinePlanColumn( relnew, ColumnDate := macroPlan.StartOfPlanning().Date() - 1 ); 
 | 
    traverse ( opt, OfflinePlanRow, opr ) { 
 | 
      if ( opr.Type() = "0" ) { 
 | 
        productLineCell := productOPC.OfflinePlanCell( relnew, Value := opr.ProductionLine() ); 
 | 
        productLineCell.OfflinePlanRow( relset, opr ); 
 | 
      } else if( opr.Type() = "1" ) { 
 | 
        productCell := productOPC.OfflinePlanCell( relnew, Value := opr.ProductID() + ifexpr( opr.Notes() = "", "", "-" + opr.Notes() ) ); 
 | 
        productCell.OfflinePlanRow( relset, opr ); 
 | 
        typeCell    := typeOPC.OfflinePlanCell( relnew, Value :=  "Quantity" ); 
 | 
        typeCell.OfflinePlanRow( relset, opr ); 
 | 
      } else if ( opr.Type() = "2" ) { 
 | 
        typeCell    := typeOPC.OfflinePlanCell( relnew, Value :=  "Order" ); 
 | 
        typeCell.OfflinePlanRow( relset, opr ); 
 | 
      } else if ( opr.Type() = "3" ) { 
 | 
        totalCell := productOPC.OfflinePlanCell( relnew, Value := "合计" ); 
 | 
        totalCell.OfflinePlanRow( relset, opr ); 
 | 
        totalCell := typeOPC.OfflinePlanCell( relnew, Value :=  "总量" ); 
 | 
        totalCell.OfflinePlanRow( relset, opr ); 
 | 
      } else if ( opr.Type() = "4" ) { 
 | 
        shiftCell := typeOPC.OfflinePlanCell( relnew, Value :=  "班次" ); 
 | 
        shiftCell.OfflinePlanRow( relset, opr ); 
 | 
      } else if ( opr.Type() = "5" ) { 
 | 
        shiftStartDateCell := typeOPC.OfflinePlanCell( relnew, Value :=  "班次开始时间" ); 
 | 
        shiftStartDateCell.OfflinePlanRow( relset, opr ); 
 | 
      } else if ( opr.Type() = "6" ) { 
 | 
        shiftEndDateCell := typeOPC.OfflinePlanCell( relnew, Value :=  "班次结束时间" ); 
 | 
        shiftEndDateCell.OfflinePlanRow( relset, opr ); 
 | 
      } 
 | 
    } 
 | 
     
 | 
    // 补全总量&班次&班次开始时间&班次结束时间 
 | 
    totalOPRs          := selectset( opt, OfflinePlanRow, tempOPR, tempOPR.Type() = "3" ); 
 | 
    shiftOPRs          := selectset( opt, OfflinePlanRow, tempOPR, tempOPR.Type() = "4" ); 
 | 
    shiftStartDateOPRs := selectset( opt, OfflinePlanRow, tempOPR, tempOPR.Type() = "5" ); 
 | 
    shiftEndDateOPRs   := selectset( opt, OfflinePlanRow, tempOPR, tempOPR.Type() = "6" ); 
 | 
    traverse ( opt, OfflinePlanColumn, opc, opc.OfflinePlanCell( relsize ) > 0 and opc.ColumnDate() >= macroPlan.StartOfPlanning().Date() ) { 
 | 
      traverse ( totalOPRs, Elements, totalOPR ) { 
 | 
        total     := sum( opc, OfflinePlanCell, tempOPC, tempOPC.OfflinePlanRow().ProductionLine() = totalOPR.ProductionLine() and tempOPC.OfflinePlanRow().Type() = "1", [Real]tempOPC.Value() ); 
 | 
        totalCell := opc.OfflinePlanCell( relnew, Value := [String]total ); 
 | 
        totalCell.OfflinePlanRow( relset, totalOPR ); 
 | 
      } 
 | 
       
 | 
      traverse ( shiftOPRs, Elements, shiftOPR ) { 
 | 
        shift := select( opc, OfflinePlanCell, tempOPC, tempOPC.OfflinePlanRow().ProductionLine() = shiftOPR.ProductionLine() and tempOPC.OfflinePlanRow().Type() = "1" );  
 | 
        if ( not isnull( shift ) ) { 
 | 
          shiftCell := opc.OfflinePlanCell( relnew, Value := shift.Shift() ); 
 | 
          shiftCell.OfflinePlanRow( relset, shiftOPR ); 
 | 
        } 
 | 
      } 
 | 
       
 | 
      traverse ( shiftStartDateOPRs, Elements, ssdOPR ) { 
 | 
        shift := select( opc, OfflinePlanCell, tempOPC, tempOPC.OfflinePlanRow().ProductionLine() = ssdOPR.ProductionLine() and tempOPC.OfflinePlanRow().Type() = "1" );  
 | 
        if ( not isnull( shift ) ) { 
 | 
          startDate     := guard( minselect( macroPlan, ShiftPattern.ShiftDayTime, tempSDT, tempSDT.ShiftPattern().Name() = shift.Shift(), tempSDT.Sequence() ).StartDateTime().Format( "H:m" ), "" ); 
 | 
          startDateCell := opc.OfflinePlanCell( relnew, Value := startDate ); 
 | 
          startDateCell.OfflinePlanRow( relset, ssdOPR ); 
 | 
        } 
 | 
      } 
 | 
       
 | 
      traverse ( shiftEndDateOPRs, Elements, sedOPR ) { 
 | 
        shift := select( opc, OfflinePlanCell, tempOPC, tempOPC.OfflinePlanRow().ProductionLine() = sedOPR.ProductionLine() and tempOPC.OfflinePlanRow().Type() = "1" );  
 | 
        if ( not isnull( shift ) ) { 
 | 
          endDate     := guard( maxselect( macroPlan, ShiftPattern.ShiftDayTime, tempSDT, tempSDT.ShiftPattern().Name() = shift.Shift(), tempSDT.Sequence() ).EndDateTIme().Format( "H:m" ), "" ); 
 | 
          endDateCell := opc.OfflinePlanCell( relnew, Value := endDate ); 
 | 
          endDateCell.OfflinePlanRow( relset, sedOPR ); 
 | 
        } 
 | 
      } 
 | 
    } 
 | 
     
 | 
    // 补全时间列 
 | 
    indexDate := macroPlan.StartOfPlanning().Date(); 
 | 
    endDate   := Date::Construct( indexDate.Year(), 12, 31 ); 
 | 
    while ( indexDate <= endDate ) { 
 | 
      opc := select( opt, OfflinePlanColumn, tempOPC, tempOPC.ColumnDate() = indexDate ); 
 | 
      if ( isnull( opc ) ) { 
 | 
        opc := opt.OfflinePlanColumn( relnew, ColumnDate := indexDate ); 
 | 
      } 
 | 
      indexDate := indexDate + 1; 
 | 
    } 
 | 
     
 | 
    Transaction::Transaction().PropagateAll(); 
 | 
     
 | 
    // 设置生产顺序 
 | 
    productionLines := selectuniquevalues( opt, OfflinePlanRow, tempOPR, true, tempOPR.ProductionLine() ); 
 | 
    traverse ( productionLines, Elements, pl ) { 
 | 
      indexColumn    := select( opt, OfflinePlanColumn, tempOPC, tempOPC.ColumnDate() = macroPlan.StartOfPlanning().Date() ); 
 | 
      previousColumn := indexColumn.PreviousColumn(); 
 | 
      nextColumn     := indexColumn.NextColumn(); 
 | 
       
 | 
      while ( not isnull( indexColumn.NextColumn() ) ) { 
 | 
        productionSerialNumber := 1; 
 | 
        opcs                   := selectsortedset( indexColumn, OfflinePlanCell, tempOPC, tempOPC.FindType( "2", pl ), tempOPC.InventoryWeight() ); 
 | 
        if ( opcs.Size() > 0 ) { 
 | 
          // 判定1 
 | 
          previousOPC := maxselect( previousColumn, OfflinePlanCell, tempOPC, tempOPC.FindType( "2", pl ), tempOPC.ProductionSerialNumber() ); 
 | 
          if ( isnull( previousOPC ) or indexColumn.ColumnDate() = macroPlan.StartOfPlanning().Date() ) { 
 | 
            opc := opcs.Element( 0 ); 
 | 
            opc.Value( "#" + productionSerialNumber.Format( "N(LPad0(2))" ) ); 
 | 
            opc.ProductionSerialNumber( productionSerialNumber ); 
 | 
            productionSerialNumber++; 
 | 
            opcs.Remove( opc ); 
 | 
          } else { 
 | 
            opc := select( opcs, Elements, tempOPC, tempOPC.OfflinePlanRow().ProductID() = previousOPC.OfflinePlanRow().ProductID() ); 
 | 
            if ( not isnull( opc ) ) { 
 | 
              opc.Value( "#" + productionSerialNumber.Format( "N(LPad0(2))" ) ); 
 | 
              opc.ProductionSerialNumber( productionSerialNumber ); 
 | 
              productionSerialNumber++; 
 | 
              opcs.Remove( opc ); 
 | 
            } 
 | 
          } 
 | 
           
 | 
          // 判定2 
 | 
          nextOPCs := selectset( opcs, Elements, tempOPC, 
 | 
                                 exists( nextColumn, OfflinePlanCell, nextOPC, nextOPC.FindType( "2", pl ) and nextOPC.OfflinePlanRow().ProductID() = tempOPC.OfflinePlanRow().ProductID() ) ); 
 | 
          if ( nextOPCs.Size() = 1 ) { 
 | 
            opc := nextOPCs.Element( 0 ); 
 | 
            opc.Value( "#" + opcs.Size().Format( "N(LPad0(2))" ) ); 
 | 
            opc.ProductionSerialNumber( opcs.Size() ); 
 | 
            opcs.Remove( opc ); 
 | 
          } 
 | 
           
 | 
          // 判定3 
 | 
          traverse ( opcs, Elements, opc ) { 
 | 
            opc.Value( "#" + productionSerialNumber.Format( "N(LPad0(2))" ) ); 
 | 
            opc.ProductionSerialNumber( productionSerialNumber ); 
 | 
            productionSerialNumber++; 
 | 
            opcs.Remove( opc ); 
 | 
          } 
 | 
        } 
 | 
         
 | 
        indexColumn    := indexColumn.NextColumn(); 
 | 
        previousColumn := indexColumn.PreviousColumn(); 
 | 
        nextColumn     := indexColumn.NextColumn(); 
 | 
      } 
 | 
    } 
 | 
  *] 
 | 
} 
 |