admin
2025-01-22 7e31442f0e9b07764e9c6a9680d3d4aeba5fe1de
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
Quintiq file version 2.0
#parent: #root
Method CapacityRounding (
  MacroPlan macroPlan,
  Real timeDifference,
  UnitPeriodTimeBase uptb,
  UnitPeriodTimeBases uptbs
)
{
  TextBody:
  [*
    debuginfo( "需要圆整的时间(单位:小时)", timeDifference, "    Free capacity(单位:小时)", uptb.FreeCapacity().HoursAsReal(), "    ChangeoverDuration(单位:小时)", uptb.ChangeoverDuration().HoursAsReal(), "    需要圆整的产能周期的开始时间:", uptb.StartDate().Format( "Y-M2-D2" ) );
    //timeDifference         := uptb.FreeCapacity().HoursAsReal() - uptb.ChangeoverDuration().HoursAsReal();
    nextUnitPeriodTimeBase := ifexpr( isnull( uptb.Next().astype( UnitPeriodTimeBase ) ), select( uptbs, Elements, tempUPTB, tempUPTB.Start() = uptb.End() ), uptb.Next().astype( UnitPeriodTimeBase ) );
    //debuginfo( "考虑库存和lotsize" );
    //while ( timeDifference > 0 and not isnull( nextUnitPeriodTimeBase ) ) {
    //  debuginfo( "开始向时间为:", nextUnitPeriodTimeBase.StartDate().Format( "Y-M2-D2" ), "的产能周期借" );
    //      
    //  traverse ( nextUnitPeriodTimeBase, PeriodTaskOperation, pto, guard( pto.Operation().RoutingStep().Routing().Start(), uptb.StartDate() ) <= uptb.StartDate() and
    //                                                               guard( pto.Operation().RoutingStep().Routing().End(), uptb.End().Date() ) >= uptb.End().Date() and
    //                                                               timeDifference > 0 ) {         
    //    minimumQuantityThatCanBeBorrowed := Real::MaxReal();
    //    minimumCapacityThatCanBeBorrowed := Real::MaxReal();
    //    traverse ( pto, NewSupply, ns, true ) {
    //      targetBorrowSplitShiftLotsizeLimit := select( scenarioManager, SplitShiftLotsizeLimit, tempSSLL, tempSSLL.unitID() = unitPeriodTimeBase.UnitID() and
    //                                                                                                       tempSSLL.productID() = ns.ProductInStockingPointInPeriodPlanningLeaf().ProductInStockingPoint_MP().ProductID() and
    //                                                                                                       tempSSLL.startTime() <= ns.Start().Date() and
    //                                                                                                       tempSSLL.endTime() >= ns.End().Date() );
    //      minimumQuantityThatCanBeBorrowed := minvalue( 
    //                                                    minvalue( ifexpr( not isnull( targetBorrowSplitShiftLotsizeLimit ) and targetBorrowSplitShiftLotsizeLimit.lotsize() < ns.Quantity(), 
    //                                                                      ns.Quantity() - targetBorrowSplitShiftLotsizeLimit.lotsize(), 
    //                                                                      Real::MaxReal() ),
    //                                                              minvalue( 
    //                                                                        ifexpr( ( ns.ProductInStockingPointInPeriodPlanningLeaf().InventoryLevelEnd() - ns.ProductInStockingPointInPeriodPlanningLeaf().MinInventoryLevel() ) > 0, 
    //                                                                                  ns.ProductInStockingPointInPeriodPlanningLeaf().InventoryLevelEnd() - ns.ProductInStockingPointInPeriodPlanningLeaf().MinInventoryLevel(), 
    //                                                                                  0.0 
    //                                                                               ), 
    //                                                                        ns.Quantity()    
    //                                                                       ) 
    //                                                             ),
    //                                                    minimumCapacityThatCanBeBorrowed 
    //                                                   );
    //      debuginfo( "nextUnitPeriodTimeBase的当前周期任务供应的产品名:", ns.ProductInStockingPointInPeriodPlanningLeaf().ProductInStockingPoint_MP().ProductID(), String::Tab(),
    //                 "最小库存:", ns.ProductInStockingPointInPeriodPlanningLeaf().MinInventoryLevel(), String::Tab(),
    //                 "现有库存:", ns.ProductInStockingPointInPeriodPlanningLeaf().InventoryLevelEnd(), String::Tab(),
    //                 "供应数量:", ns.Quantity(), String::Tab(),
    //                 "是否存在lotsize:", ifexpr( isnull( targetBorrowSplitShiftLotsizeLimit ), "不存在", "存在" ), String::Tab(),
    //                 "lotsize数量:", ifexpr( isnull( targetBorrowSplitShiftLotsizeLimit ), -1, targetBorrowSplitShiftLotsizeLimit.lotsize() )
    //                );
    //                    
    //      sourceProductInStockingPointInPeriodPlanningLeaf := select( ns, ProductInStockingPointInPeriodPlanningLeaf.ProductInStockingPoint_MP.ProductInStockingPointInPeriodPlanning.astype( ProductInStockingPointInPeriodPlanningLeaf ), tempPISPIPPL, tempPISPIPPL.Start() = unitPeriodTimeBase.Start() );
    //      sourceNewSupply := select( sourceProductInStockingPointInPeriodPlanningLeaf, NewSupply, tempNS, tempNS.Process_MP().AsProcess_MP().ID() = unitPeriodTimeBase.UnitID() );
    //      targetReturnSplitShiftLotsizeLimit := select( scenarioManager, SplitShiftLotsizeLimit, tempSSLL, tempSSLL.unitID() = unitPeriodTimeBase.UnitID() and
    //                                                                                                       tempSSLL.productID() = sourceProductInStockingPointInPeriodPlanningLeaf.ProductInStockingPoint_MP().ProductID() and
    //                                                                                                       tempSSLL.startTime() <= sourceProductInStockingPointInPeriodPlanningLeaf.Start().Date() and
    //                                                                                                       tempSSLL.endTime() >= sourceProductInStockingPointInPeriodPlanningLeaf.End().Date() );
    //      minimumAcceptableQuantity := minvalue( ifexpr( not isnull( targetReturnSplitShiftLotsizeLimit ) and not isnull( sourceNewSupply ) and targetReturnSplitShiftLotsizeLimit.lotsize() > sourceNewSupply.Quantity(), 
    //                                                     targetReturnSplitShiftLotsizeLimit.lotsize() - sourceNewSupply.Quantity(), 
    //                                                     Real::MaxReal() 
    //                                                    ),
    //                                             ifexpr( ( sourceProductInStockingPointInPeriodPlanningLeaf.MaxInventoryLevel() - sourceProductInStockingPointInPeriodPlanningLeaf.InventoryLevelEnd() ) > 0, 
    //                                                       sourceProductInStockingPointInPeriodPlanningLeaf.MaxInventoryLevel() - sourceProductInStockingPointInPeriodPlanningLeaf.InventoryLevelEnd(), 
    //                                                       0.0 
    //                                                    )
    //                                            );                                            
    //      debuginfo( "要圆整的时间:", sourceProductInStockingPointInPeriodPlanningLeaf.Start().Date().Format( "Y-M2-D2" ), String::Tab(),
    //                 "要圆整的最大库存:", sourceProductInStockingPointInPeriodPlanningLeaf.MaxInventoryLevel(), String::Tab(),
    //                 "要圆整的现有库存:", sourceProductInStockingPointInPeriodPlanningLeaf.InventoryLevelEnd(), String::Tab(),
    //                 "要圆整的供应数量:", guard( sourceNewSupply.Quantity(), 0 ), String::Tab(),
    //                 "是否存在lotsize:", ifexpr( isnull( targetReturnSplitShiftLotsizeLimit ), "不存在", "存在" ), String::Tab(),
    //                 "lotsize数量:", ifexpr( isnull( targetReturnSplitShiftLotsizeLimit ), -1, targetReturnSplitShiftLotsizeLimit.lotsize() ), String::Tab(),
    //                 "要圆整的最小接纳数量:", minimumAcceptableQuantity
    //                );
    //        
    //      minimumQuantityThatCanBeBorrowed := minvalue( minimumQuantityThatCanBeBorrowed, minimumAcceptableQuantity );
    //    }
    //    debuginfo( "nextUnitPeriodTimeBase的当前周期任务供应数量:", pto.Quantity(), "    周期任务能借的最低数量:", minimumQuantityThatCanBeBorrowed );                                                     
    //      
    //    minimumCapacityThatCanBeBorrowed := minimumQuantityThatCanBeBorrowed / pto.Operation().Throughput();
    //    unifiedProcessingTimeOfRounding := minvalue( timeDifference, minimumCapacityThatCanBeBorrowed ); 
    //    debuginfo( "剩余圆整的产能:", timeDifference, "    nextUnitPeriodTimeBase的当前周期任务供应数量:", pto.Quantity(), "    能借的产能:", minimumCapacityThatCanBeBorrowed, " 统一借的产能:", unifiedProcessingTimeOfRounding ); 
    //    this.A_unifiedProcessingOfRoundingLogic( unifiedProcessingTimeOfRounding, unitPeriodTimeBase, pto, macroPlan );  
    //    timeDifference := timeDifference - unifiedProcessingTimeOfRounding;  
    //  }
    //     
    //  if ( isnull( nextUnitPeriodTimeBase.Next() ) ) {
    //    nextUnitPeriodTimeBase := select( unitPeriodTimeBases, Elements, tempUPTB, tempUPTB.Start() = nextUnitPeriodTimeBase.End() );
    //  } else {
    //    nextUnitPeriodTimeBase := nextUnitPeriodTimeBase.Next().astype( UnitPeriodTimeBase );
    //  }
    //  debuginfo( "。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。" );
    //}
    
    sourceChangeover := uptb.ChangeoverDuration();
    targetChangeover := Duration::Zero();
    
    debuginfo( "需要圆整的时间(单位:小时)", timeDifference, "    考虑ChangeOver条件圆整使其达到整班" );
    nextUnitPeriodTimeBase := ifexpr( isnull( uptb.Next().astype( UnitPeriodTimeBase ) ), select( uptbs, Elements, tempUPTB, tempUPTB.Start() = uptb.End() ), uptb.Next().astype( UnitPeriodTimeBase ) );
    while ( timeDifference > 0 and not isnull( nextUnitPeriodTimeBase ) ) {
      debuginfo( "开始向时间为:", nextUnitPeriodTimeBase.StartDate().Format( "Y-M2-D2" ), "的产能周期借" );
      traverse ( nextUnitPeriodTimeBase, PeriodTaskOperation, pto, guard( pto.Operation().RoutingStep().Routing().Start(), uptb.StartDate() ) <= uptb.StartDate() and
                                                                   guard( pto.Operation().RoutingStep().Routing().End(), uptb.End().Date() ) >= uptb.End().Date() and
                                                                   exists( uptb, PeriodTaskOperation.Operation, tempO, tempO = pto.Operation() )                  and
                                                                   timeDifference > 0 ) {
        minimumCapacityThatCanBeBorrowed := pto.Quantity() / pto.Operation().Throughput();
        unifiedProcessingTimeOfRounding := minvalue( timeDifference, minimumCapacityThatCanBeBorrowed ); 
        debuginfo( "剩余圆整的产能:", timeDifference, "    nextUnitPeriodTimeBase的当前周期任务供应数量:", pto.Quantity(), "    能借的产能:", minimumCapacityThatCanBeBorrowed, " 统一借的产能:", unifiedProcessingTimeOfRounding, "    借之前changeover时间:", uptb.ChangeoverDuration() ); 
        this.UnifiedProcessingOfRoundingLogic( unifiedProcessingTimeOfRounding, uptb, pto, macroPlan ); 
        targetChangeover := uptb.ChangeoverDuration();
        timeDifference   := timeDifference - unifiedProcessingTimeOfRounding;                                                 
      }
         
      if ( isnull( nextUnitPeriodTimeBase.Next() ) ) {
        nextUnitPeriodTimeBase := select( uptbs, Elements, tempUPTB, tempUPTB.Start() = nextUnitPeriodTimeBase.End() );
      } else {
        nextUnitPeriodTimeBase := nextUnitPeriodTimeBase.Next().astype( UnitPeriodTimeBase );
      }
    }
        
    debuginfo( "需要圆整的时间(单位:小时)", timeDifference, "    不考虑任何条件圆整使其到达整班" );
    nextUnitPeriodTimeBase := ifexpr( isnull( uptb.Next().astype( UnitPeriodTimeBase ) ), select( uptbs, Elements, tempUPTB, tempUPTB.Start() = uptb.End() ), uptb.Next().astype( UnitPeriodTimeBase ) );
    while ( timeDifference > 0 and not isnull( nextUnitPeriodTimeBase ) ) {
      debuginfo( "开始向时间为:", nextUnitPeriodTimeBase.StartDate().Format( "Y-M2-D2" ), "的产能周期借" );
      traverse ( nextUnitPeriodTimeBase, PeriodTaskOperation, pto, guard( pto.Operation().RoutingStep().Routing().Start(), uptb.StartDate() ) <= uptb.StartDate() and
                                                                   guard( pto.Operation().RoutingStep().Routing().End(), uptb.End().Date() ) >= uptb.End().Date() and
                                                                   timeDifference > 0 ) {
        minimumCapacityThatCanBeBorrowed := pto.Quantity() / pto.Operation().Throughput();
        unifiedProcessingTimeOfRounding := minvalue( timeDifference, minimumCapacityThatCanBeBorrowed ); 
        debuginfo( "剩余圆整的产能:", timeDifference, "    nextUnitPeriodTimeBase的当前周期任务供应数量:", pto.Quantity(), "    能借的产能:", minimumCapacityThatCanBeBorrowed, " 统一借的产能:", unifiedProcessingTimeOfRounding, "    当前changeover时间:", uptb.ChangeoverDuration().HoursAsReal() ); 
        this.UnifiedProcessingOfRoundingLogic( unifiedProcessingTimeOfRounding, uptb, pto, macroPlan );  
        timeDifference := timeDifference - unifiedProcessingTimeOfRounding;                                                 
      }
         
      if ( isnull( nextUnitPeriodTimeBase.Next() ) ) {
        nextUnitPeriodTimeBase := select( uptbs, Elements, tempUPTB, tempUPTB.Start() = nextUnitPeriodTimeBase.End() );
      } else {
        nextUnitPeriodTimeBase := nextUnitPeriodTimeBase.Next().astype( UnitPeriodTimeBase );
      }
    }
    
    if ( ( targetChangeover - sourceChangeover ).HoursAsReal() > 0.0 ) {
      this.ZeroCapacityReplenishment( macroPlan, ( targetChangeover - sourceChangeover ).HoursAsReal(), uptb, uptbs );
    }
  *]
}