|
|
|
@ -49,61 +49,6 @@ import static com.dsic.gj_erp.pc.Manager.*;
|
|
|
|
|
@Slf4j
|
|
|
|
|
public class DataFactory {
|
|
|
|
|
|
|
|
|
|
public static void 排产2() {
|
|
|
|
|
装载中日程数据();
|
|
|
|
|
套料图所占工序的资源.clear();
|
|
|
|
|
Manager.排产结果=new ArrayList<>();
|
|
|
|
|
List<钢料需求> list=读取钢料需求();
|
|
|
|
|
工序CD接口 _工序CD接口 = getBean(工序CD接口.class);
|
|
|
|
|
List<工序CD> 工序CDS = _工序CD接口.get();
|
|
|
|
|
Map<Constant.工序,工序CD> 工序CDMap=new HashMap<>();
|
|
|
|
|
工序CDS.forEach(item->工序CDMap.put(item.getGx(),item));
|
|
|
|
|
|
|
|
|
|
执行排产(list,工序CDMap);
|
|
|
|
|
|
|
|
|
|
清理冗余数据(list);
|
|
|
|
|
|
|
|
|
|
if (Manager.排产结果.size()>0){
|
|
|
|
|
log.info("排产异常--{}个未完整排产,{}",Manager.排产结果.size(),Manager.排产结果);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void 执行排产(List<钢料需求> list, Map<Constant.工序, 工序CD> 工序CDMap){
|
|
|
|
|
list.forEach(钢料需求 -> {
|
|
|
|
|
CountDownLatch latch = new CountDownLatch(钢料需求.getBomList().size());
|
|
|
|
|
String xzglxq = 钢料需求.getXzglxq();
|
|
|
|
|
String dzglxq = 钢料需求.getDzglxq();
|
|
|
|
|
|
|
|
|
|
钢料需求.getBomList().forEach(bom -> {
|
|
|
|
|
套料图工序 _套料图工序 = 套料图工序工厂(bom);
|
|
|
|
|
|
|
|
|
|
//套料图未定义/定义错误
|
|
|
|
|
if (_套料图工序==null){
|
|
|
|
|
latch.countDown();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_套料图工序.setXzglxq(xzglxq);
|
|
|
|
|
_套料图工序.setDzglxq(dzglxq);
|
|
|
|
|
_套料图工序.set工序CD(工序CDMap);
|
|
|
|
|
_套料图工序.set中日程(获取中日程(bom.getDcch() + bom.getPl() + bom.getFd()));
|
|
|
|
|
|
|
|
|
|
es.execute(() -> {
|
|
|
|
|
try{
|
|
|
|
|
_套料图工序.run();
|
|
|
|
|
}finally {
|
|
|
|
|
latch.countDown();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
try {
|
|
|
|
|
latch.await(10, TimeUnit.SECONDS);// 指定超时时间
|
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static DmZrcjh 获取中日程(String key){
|
|
|
|
|
return getBean(DmZrcjhService.class).排产获取中日程数据(key);
|
|
|
|
|
}
|
|
|
|
@ -125,24 +70,6 @@ public class DataFactory {
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void 排产3(){
|
|
|
|
|
装载中日程数据();
|
|
|
|
|
套料图所占工序的资源.clear();
|
|
|
|
|
Manager.排产结果=new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
List<钢料需求> list=读取钢料需求();
|
|
|
|
|
Collection<按批次合并的钢料需求> 按批次合并 = 按批次合并(list);
|
|
|
|
|
计算需求产能(按批次合并);
|
|
|
|
|
try {
|
|
|
|
|
均衡预占(按批次合并);
|
|
|
|
|
}catch (Exception e){
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}finally {
|
|
|
|
|
清理冗余数据(list);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void 排产4(){
|
|
|
|
|
装载中日程数据();
|
|
|
|
|
套料图所占工序的资源.clear();
|
|
|
|
@ -207,9 +134,6 @@ public class DataFactory {
|
|
|
|
|
//记录6次计算的全部资源
|
|
|
|
|
tmpList.add(_资源);
|
|
|
|
|
if (_资源.判断切割设备是否可以被占用(切割各设备需求量)){
|
|
|
|
|
if (item.getDcCh().equals("G175K-5")&&item.getDcPl().equals("003")){
|
|
|
|
|
System.out.println(111);
|
|
|
|
|
}
|
|
|
|
|
执行排产(item.getBomList(),item.get均衡需求日期(),工序CDMap);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
@ -224,11 +148,7 @@ public class DataFactory {
|
|
|
|
|
//查找最小可用资源,进行占用
|
|
|
|
|
tmpList.sort(Comparator.comparingDouble((tmp)->tmp.get工序产能MAP().get(Constant.工序.切割).get占用()));
|
|
|
|
|
tmpList.stream().findFirst().ifPresent(tmp->{
|
|
|
|
|
//由于资源日为切割日期,这里需要还原一下,修正传递的参照需求日期
|
|
|
|
|
DateTime offset = tmp.get_date().offset(DateField.DAY_OF_MONTH, -工序CDMap.get(依据工序).getCd());
|
|
|
|
|
if (item.getDcCh().equals("G175K-5")&&item.getDcPl().equals("003")){
|
|
|
|
|
System.out.println(offset.toDateStr());
|
|
|
|
|
}
|
|
|
|
|
DateTime offset = DateUtil.parse(tmp.getDate()).offset(DateField.DAY_OF_MONTH, -工序CDMap.get(依据工序).getCd());
|
|
|
|
|
执行排产(item.getBomList(),offset,工序CDMap);
|
|
|
|
|
date.set(tmp.getDate());
|
|
|
|
|
});
|
|
|
|
@ -242,91 +162,6 @@ public class DataFactory {
|
|
|
|
|
log.info("船号:{},批次:{},占用资源成功,切割日期:{}",item.getDcCh(),item.getDcPl(),date.get());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void 均衡预占(Collection<按批次合并的钢料需求> _按批次合并的钢料需求){
|
|
|
|
|
工序CD接口 _工序CD接口 = getBean(工序CD接口.class);
|
|
|
|
|
List<工序CD> 工序CDS = _工序CD接口.get();
|
|
|
|
|
Map<Constant.工序,工序CD> 工序CDMap=new HashMap<>();
|
|
|
|
|
工序CDS.forEach(item->工序CDMap.put(item.getGx(),item));
|
|
|
|
|
|
|
|
|
|
for (按批次合并的钢料需求 item:_按批次合并的钢料需求){
|
|
|
|
|
if (ObjUtil.isNotEmpty(item.getBomList())){
|
|
|
|
|
均衡计算(item,工序CDMap);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void 均衡计算(按批次合并的钢料需求 item,Map<Constant.工序,工序CD> 工序CDMap){
|
|
|
|
|
Constant.工序 依据工序=Constant.工序.切割;
|
|
|
|
|
//需求日期可利用范围是±3天
|
|
|
|
|
int times=-3;
|
|
|
|
|
List<资源> tmpList=new ArrayList<>();
|
|
|
|
|
AtomicDouble atomicDouble = item.get产能需求().get(依据工序);
|
|
|
|
|
资源 _资源=null;
|
|
|
|
|
do {
|
|
|
|
|
//因为第一次计算时候就是当前批量小组需求日期,所以再次循环到的时候不需要再次计算
|
|
|
|
|
if (times==0){
|
|
|
|
|
times+=1;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (times>3){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
DateTime xzglxq = item.get均衡需求日期().offset(DateField.DAY_OF_YEAR,工序CDMap.get(依据工序).getCd());
|
|
|
|
|
if (xzglxq.isBefore(DateUtil.date())){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
_资源 = 提取资源(xzglxq);
|
|
|
|
|
if (_资源.get_date().isBefore(DateUtil.date())){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
tmpList.add(_资源);
|
|
|
|
|
if (_资源.判断工序是否可以被占用(依据工序,atomicDouble.get())){
|
|
|
|
|
// DateTime 上料日期 = item.get均衡需求日期().offset(DateField.DAY_OF_YEAR, -14);
|
|
|
|
|
// 资源 上料 = 提取资源(上料日期);
|
|
|
|
|
// for (Bom bom:item.getBomList()){
|
|
|
|
|
// 上料.占用资源(Constant.工序.上料,bom,item.get产能需求().get(Constant.工序.上料).get());
|
|
|
|
|
// _资源.占用资源(Constant.工序.切割,bom,1);
|
|
|
|
|
// }
|
|
|
|
|
if (item.getDcCh().equals("G175K-4")&&item.getDcPl().equals("020")){
|
|
|
|
|
System.out.println(111);
|
|
|
|
|
}
|
|
|
|
|
执行排产(item.getBomList(),item.get均衡需求日期(),工序CDMap);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
//需求日期可利用范围是±3天,排产是需要根据产能进行调整
|
|
|
|
|
item.set均衡需求日期(DateUtil.offsetDay(item.get均衡需求日期(),times));
|
|
|
|
|
times+=1;
|
|
|
|
|
}while (true);
|
|
|
|
|
|
|
|
|
|
//若在需求期±3天内无法正常排产时,查找最大可用空闲资源进行占用
|
|
|
|
|
AtomicReference<String> date=new AtomicReference<>();
|
|
|
|
|
if (times>3){
|
|
|
|
|
//查找最小可用资源,进行占用
|
|
|
|
|
tmpList.sort(Comparator.comparingDouble((tmp)->tmp.get工序产能MAP().get(Constant.工序.切割).get占用()));
|
|
|
|
|
tmpList.stream().findFirst().ifPresent(tmp->{
|
|
|
|
|
// DateTime 上料日期 = item.get均衡需求日期().offset(DateField.DAY_OF_YEAR, -14);
|
|
|
|
|
// 资源 上料 = 提取资源(上料日期);
|
|
|
|
|
// for (Bom bom:item.getBomList()){
|
|
|
|
|
// 上料.占用资源(Constant.工序.上料,bom,item.get产能需求().get(Constant.工序.上料).get());
|
|
|
|
|
// tmp.占用资源(Constant.工序.切割,bom,1);
|
|
|
|
|
// }
|
|
|
|
|
//由于资源日为切割日期,这里需要还原一下,修正传递的参照需求日期
|
|
|
|
|
if (item.getDcCh().equals("G175K-4")&&item.getDcPl().equals("020")){
|
|
|
|
|
System.out.println(111);
|
|
|
|
|
}
|
|
|
|
|
执行排产(item.getBomList(),tmp.get_date().offset(DateField.DAY_OF_YEAR,-工序CDMap.get(依据工序).getCd()),工序CDMap);
|
|
|
|
|
date.set(tmp.getDate());
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (_资源!=null){
|
|
|
|
|
date.set(_资源.getDate());
|
|
|
|
|
log.info("船号:{},批次:{},占用资源成功,切割日期:{}",item.getDcCh(),item.getDcPl(),date.get());
|
|
|
|
|
}else {
|
|
|
|
|
log.info("船号:{},批次:{},早于当前日期无需排产",item.getDcCh(),item.getDcPl());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static void 执行排产(List<Bom> list,DateTime 参照需求日期,Map<Constant.工序,工序CD> 工序CDMap){
|
|
|
|
|
CountDownLatch latch = new CountDownLatch(list.size());
|
|
|
|
|
for (Bom bom:list){
|
|
|
|
@ -358,11 +193,6 @@ public class DataFactory {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static void 计算需求产能(Collection<按批次合并的钢料需求> _按批次合并的钢料需求){
|
|
|
|
|
_按批次合并的钢料需求.forEach(按批次合并的钢料需求::计算各工序产能需求);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static List<钢料需求> 合并批次(List<钢料需求> list){
|
|
|
|
|
Map<String,钢料需求> map=new HashMap<>();
|
|
|
|
|
list.forEach(item->{
|
|
|
|
@ -377,16 +207,6 @@ public class DataFactory {
|
|
|
|
|
return new ArrayList<>(map.values());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static Collection<按批次合并的钢料需求> 按批次合并(List<钢料需求> list){
|
|
|
|
|
Map<String,按批次合并的钢料需求> map=new HashMap<>();
|
|
|
|
|
list.forEach(item->{
|
|
|
|
|
String key=item.getDcCh() + item.getDcPl();
|
|
|
|
|
按批次合并的钢料需求 _按批次合并的钢料需求 = map.computeIfAbsent(key, k -> new 按批次合并的钢料需求());
|
|
|
|
|
_按批次合并的钢料需求.of(item);
|
|
|
|
|
});
|
|
|
|
|
return map.values();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static List<钢料需求> 读取钢料需求1(){
|
|
|
|
|
List<DmSygdxq> 按需求日期排序的钢料需求 = getBean(DmSygdxqService.class).getXqWithBom(from, to);
|
|
|
|
|
return 按需求日期排序的钢料需求.stream().map(item->{
|
|
|
|
@ -396,11 +216,6 @@ public class DataFactory {
|
|
|
|
|
}).collect(Collectors.toList());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static List<钢料需求> 读取钢料需求(){
|
|
|
|
|
List<DmSygdxq> 按需求日期排序的钢料需求 = getBean(DmSygdxqService.class).getXqWithBom(from, to);
|
|
|
|
|
return 按需求日期排序的钢料需求.stream().map(钢料需求::of).collect(Collectors.toList());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static Map<String,List<订货计划>> _订货计划=new HashMap<>();
|
|
|
|
|
public static List<订货计划> 获取订货计划(String dcch){
|
|
|
|
|
List<订货计划> list=_订货计划.get(dcch);
|
|
|
|
@ -412,17 +227,6 @@ public class DataFactory {
|
|
|
|
|
return map.get(dcch);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Optional<资源> 搜索可用资源(Constant.工序 工序,Date 搜索起始日期,Date 搜索截止日期, double 需求数量){
|
|
|
|
|
return 资源池.values().stream().filter(资源->{
|
|
|
|
|
工序产能 工序产能 = 资源.get工序产能MAP().get(工序);
|
|
|
|
|
Date 资源日期=DateUtil.parse(资源.getDate(),"yyyy/MM/dd");
|
|
|
|
|
if (工序产能==null){
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return 工序产能.判断是否可以占用(需求数量)&&资源日期.after(搜索起始日期)&&资源日期.before(搜索截止日期);
|
|
|
|
|
}).findFirst();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static 资源 提取资源(Date date){
|
|
|
|
|
资源 资源 = 资源池.get(DateUtil.format(date, "yyyy/MM/dd"));
|
|
|
|
|
if (资源==null){
|
|
|
|
|