1.优化排产

master
董哲奇 2 years ago
parent 503bbee429
commit cc088a8f3c

@ -19,9 +19,8 @@ import java.util.List;
*/
public interface DmSygdxqMapper extends BaseMapper<DmSygdxq> {
List<DmSygdxq> getXqWithBom(String from,String to);
List<DmSygdxq> getXqWithBom(String from,String to,String dcch,String pl);
List<DmSygdMxLj> getSygdLjMx(String begin,String end);
}

@ -33,12 +33,14 @@ import com.dsic.gj_erp.service.jhgk.DmZrcjhService;
import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.AtomicDouble;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import static com.dsic.gj_erp.pc.Manager.排产;
@ -141,6 +143,105 @@ public class DataFactory {
}
public static void 排产4(){
装载中日程数据();
套料图所占工序的资源.clear();
Manager.排产结果=new ArrayList<>();
List<钢料需求> list=读取钢料需求1();
List<钢料需求> 按批次合并 = 合并批次(list);
try {
均衡预占(按批次合并);
}catch (Exception e){
// e.printStackTrace();
throw e;
}finally {
清理冗余数据(list);
}
}
public static void 均衡预占(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));
for (钢料需求 item:list){
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<>();
Map<String, AtomicDouble> 切割各设备需求量 = item.get切割各设备需求量();
资源 _资源=null;
Integer cd = 工序CDMap.get(依据工序).getCd();
do {
//因为第一次计算时候就是当前批量小组需求日期,所以再次循环到的时候不需要再次计算
if (times==0){
times+=1;
item.set均衡需求日期(DateUtil.offsetDay(DateUtil.parse(item.getXzglxq(),"yyyy/MM/dd"),times));
continue;
}
if (times>3){
break;
}
DateTime xzglxq = item.get均衡需求日期().offset(DateField.DAY_OF_YEAR,cd);
if (xzglxq.isBefore(DateUtil.date())){
//break;
}
_资源 = 提取资源(xzglxq);
if (_资源.get_date().isBefore(DateUtil.date())){
//break;
}
//记录6次计算的全部资源
tmpList.add(_资源);
if (_资源.判断切割设备是否可以被占用(切割各设备需求量)){
if (item.getDcCh().equals("G175K-5")&&item.getDcPl().equals("003")){
System.out.println(111);
}
执行排产(item.getBomList(),item.get均衡需求日期(),工序CDMap);
break;
}
//需求日期可利用范围是±3天,排产是需要根据产能进行调整
item.set均衡需求日期(DateUtil.offsetDay(DateUtil.parse(item.getXzglxq(),"yyyy/MM/dd"),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 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());
}
执行排产(item.getBomList(),offset,工序CDMap);
date.set(tmp.getDate());
});
}
if (_资源!=null){
date.set(_资源.getDate());
}else {
log.info("船号:{},批次:{},早于当前日期无需排产",item.getDcCh(),item.getDcPl());
return;
}
log.info("船号:{},批次:{},占用资源成功,切割日期:{}",item.getDcCh(),item.getDcPl(),date.get());
}
public static void 均衡预占(Collection<按批次合并的钢料需求> _按批次合并的钢料需求){
工序CD接口 _工序CD接口 = getBean(工序CD接口.class);
List<工序CD> 工序CDS = _工序CD接口.get();
@ -186,6 +287,9 @@ public class DataFactory {
// 上料.占用资源(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;
}
@ -195,6 +299,7 @@ public class DataFactory {
}while (true);
//若在需求期±3天内无法正常排产时,查找最大可用空闲资源进行占用
AtomicReference<String> date=new AtomicReference<>();
if (times>3){
//查找最小可用资源,进行占用
tmpList.sort(Comparator.comparingDouble((tmp)->tmp.get工序产能MAP().get(Constant.工序.切割).get占用()));
@ -206,17 +311,22 @@ public class DataFactory {
// 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){
log.info("船号:{},批次:{},占用资源成功,切割日期:{}",item.getDcCh(),item.getDcPl(),_资源.getDate());
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){
@ -224,6 +334,7 @@ public class DataFactory {
if (_套料图工序==null){
latch.countDown();
log.info("船号:{},批次:{},图纸编号:{},无法找到对应套料图",bom.getDcch(),bom.getPl(),bom.getTzbh());
continue;
}
@ -252,20 +363,39 @@ public class DataFactory {
_按批次合并的钢料需求.forEach(按批次合并的钢料需求::计算各工序产能需求);
}
private static List<钢料需求> 合并批次(List<钢料需求> list){
Map<String,钢料需求> map=new HashMap<>();
list.forEach(item->{
String key=item.getDcCh() + item.getDcPl();
钢料需求 _钢料需求 = map.get(key);
if (_钢料需求==null){
map.put(key,item);
}else{
_钢料需求.addBomList(item.getBomList());
}
});
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.get(key);
if (_按批次合并的钢料需求==null){
_按批次合并的钢料需求=new 按批次合并的钢料需求();
map.put(key,_按批次合并的钢料需求);
}
按批次合并的钢料需求 _按批次合并的钢料需求 = 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->{
钢料需求 _钢料需求 = 钢料需求.of(item);
_钢料需求.计算各设备切割需求量();
return _钢料需求;
}).collect(Collectors.toList());
}
public static List<钢料需求> 读取钢料需求(){
List<DmSygdxq> 按需求日期排序的钢料需求 = getBean(DmSygdxqService.class).getXqWithBom(from, to);
return 按需求日期排序的钢料需求.stream().map(钢料需求::of).collect(Collectors.toList());
@ -417,7 +547,13 @@ public class DataFactory {
public static void 创建产能资源池(){
资源池.clear();
DateTime _from = DateUtil.parse(from, "yyyy/MM/dd").offset(DateField.DAY_OF_YEAR,-30);
DateTime _to = DateUtil.parse(to, "yyyy/MM/dd");
工厂日历.stream().filter(item -> "1".equals(item.getXxr()))
.filter(item->{
DateTime gl = DateUtil.parse(item.getGl(), "yyyy/MM/dd");
return gl.isAfterOrEquals(_from)&&gl.isBeforeOrEquals(_to);
})
.forEach(item -> {
Map<Constant.工序, 工序产能> map = 计算日产能();
资源池.put(item.getGl(), 资源.of(item.getGl(), map));

@ -4,14 +4,13 @@ import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.dsic.gj_erp.bean.jcsj.DmBom;
import com.dsic.gj_erp.pc.Constant;
import com.dsic.gj_erp.pc.dto.gx.*;
import com.dsic.gj_erp.pc.dto.sb.*;
import com.dsic.gj_erp.pc.dto.设备;
import com.dsic.gj_erp.pc.dto.资源;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@ -49,6 +48,18 @@ public class Bom {
return _bom;
}
public boolean 判断是否为可识别跨位和切割设备的套料图(){
String[] 切割设备可加工套料图分类码= {
"N1AX","N1AD","N1LD","N2BX","N2BD","N2CX","N2CD","N2HX","N2HD","S2TX","S2TD","N3CX","N3CD",
"S3PX","S3PD","S3XX","N4PX","N4PD","N4XX","N2TX","N2TD"
};
return Arrays.stream(切割设备可加工套料图分类码).anyMatch(it->it.equals(this.获取套料图分类码()));
}
public String 获取套料图分类码(){
return this.tzbh.substring(4,8).toUpperCase();
}
public double 根据工序获取产能需求量(Constant.工序 _工序){
switch (_工序) {
case 上料:
@ -121,7 +132,6 @@ public class Bom {
this.errors.add(ErrorType.缺少大组需求期使用小组需求替代);
}
public void 超出工序产能(Constant.工序 _工序){
switch (_工序) {
case 上料:

@ -10,10 +10,7 @@ import com.google.common.util.concurrent.AtomicDouble;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
@Getter
@Setter
@ -28,21 +25,36 @@ public class 按批次合并的钢料需求 {
private String 预占资源日期;
private Map<Constant.工序, AtomicDouble> 产能需求;//fixme 要求必须所有工序都不可以打乱才能用
private Map<Constant.工序, AtomicDouble> 产能需求;
private Map<String,AtomicDouble> 设备需求;
private Map<Constant.工序, String> 预占结果;
public void 计算各工序产能需求(){
产能需求=new HashMap<>();
设备需求=new HashMap<>();
this.bomList.forEach(item->{
套料图工序 _套料图工序 = DataFactory.套料图工序工厂(item);
_套料图工序.get工序().forEach(_工序->{
AtomicDouble aDouble = 产能需求.get(_工序);
if (aDouble==null){
aDouble=new AtomicDouble(0);
产能需求.put(_工序,aDouble);
Optional.ofNullable(_套料图工序).ifPresent(it->{
this.计算产能需求(item,it);
});
this.计算设备需求(item);
});
}
private void 计算设备需求(Bom item){
if (item.getTzbh().contains("N1AX")||item.getTzbh().contains("N1AD")){
String key="N1AX-N1AD";
AtomicDouble aDouble = 设备需求.computeIfAbsent(key, k -> new AtomicDouble(0));
aDouble.addAndGet(1);
}
}
private void 计算产能需求(Bom item,套料图工序 _套料图工序){
_套料图工序.get工序().forEach(_工序->{
AtomicDouble aDouble = 产能需求.computeIfAbsent(_工序, k -> new AtomicDouble(0));
aDouble.addAndGet(item.根据工序获取产能需求量(_工序));
});
});
}
public 按批次合并的钢料需求 of(钢料需求 _钢料需求){

@ -1,11 +1,21 @@
package com.dsic.gj_erp.pc.dto.data;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.dsic.gj_erp.bean.SpringContextHolder;
import com.dsic.gj_erp.bean.jhgk.DmSygdxq;
import com.dsic.gj_erp.pc.Constant;
import com.dsic.gj_erp.pc.service.设备产能接口;
import com.dsic.gj_erp.pc.设备产能;
import com.google.common.util.concurrent.AtomicDouble;
import lombok.Getter;
import lombok.Setter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Getter
@ -17,11 +27,64 @@ public class 钢料需求 {
private String xzglxq;
private String dzglxq;
private List<Bom> bomList;
private Map<String, AtomicDouble> 切割各设备需求量;
private DateTime 均衡需求日期;
public static 钢料需求 of(DmSygdxq qfxq){
钢料需求 _钢料需求 = new 钢料需求();
BeanUtil.copyProperties(qfxq,_钢料需求,"bomList");
_钢料需求.bomList=qfxq.getBomList().stream().map(item->Bom.of(_钢料需求.getXzglxq(),_钢料需求.getDzglxq(),item)).collect(Collectors.toList());
_钢料需求.bomList=qfxq.getBomList().stream()
.map(item->Bom.of(_钢料需求.getXzglxq(),_钢料需求.getDzglxq(),item))
.collect(Collectors.toList());
return _钢料需求;
}
/**
* 校验产能是否满足切割需求量
*/
public void 校验产能是否满足切割需求量(){
//从redis获取各切割设备产能
设备产能接口 _设备产能接口 = getBean(设备产能接口.class);
List<设备产能> 切割设备产能 = _设备产能接口.get().stream()
.filter(item->item.get_工序()== Constant.工序.切割).collect(Collectors.toList());
}
public void 计算各设备切割需求量(){
切割各设备需求量=new HashMap<>();
this.bomList.forEach(item->{
this.切割(item,"N1AX-N1AD");//一跨龙门
this.切割(item,"N1LD");//一跨数控
this.切割(item,"N2BX-N2BD-N2CX-N2CD-N2HX-N2HD");//二跨
// this.切割(item,"N2TX-N2TD");//二跨转移4,5,6垮
this.切割(item,"S2TX-S2TD");//二跨手工
this.切割(item,"N3CX-N3CD");//三跨
this.切割(item,"S3PX-S3PD");//三跨手工
this.切割(item,"S3XX");//三跨手工
this.切割(item,"N4PX-N4PD-N4XX-N2TX-N2TD");//456垮
});
}
public void addBomList(List<Bom> list){
this.bomList.addAll(list);
}
private void 切割(Bom item,String key){
if (StrUtil.containsAny(item.getTzbh(),key.split("-"))){
AtomicDouble aDouble = 切割各设备需求量.computeIfAbsent(key, k -> new AtomicDouble(0));
aDouble.addAndGet(1);//按张计算
}
}
private static <T> T getBean(Class<T> clazz) {
return SpringContextHolder.getBean(clazz);
}
public DateTime get均衡需求日期(){
if (this.均衡需求日期 ==null){
return DateUtil.parse(this.xzglxq,"yyyy/MM/dd");
}
return this.均衡需求日期;
}
}

@ -19,14 +19,13 @@ public class 工序01上料 extends 工序产能 {
@Override
public void 计算工作量() {
this.产能=0;
if (this.白班时长>0){
this.产能+=this.白班时长*Constant.设备产能.上料01.get白班设备产能()/7.0;
}
if (this.二班时长>0){
this.产能+=this.二班时长*Constant.设备产能.上料01.get二班设备产能()/7.0;
}
this.设备.values().forEach(设备->{
设备.修正工作量(this.白班时长,this.二班时长);
this.产能+=设备.get产能();
});
}
@Override
public void 占用资源(double 所需产能) {
super.占用资源(1.0);

@ -18,14 +18,13 @@ public class 工序02抛丸 extends 工序产能 {
@Override
public void 计算工作量() {
this.产能=0;
if (this.白班时长>0){
this.产能+=this.白班时长*Constant.设备产能.抛丸01.get白班设备产能()/7.0;
}
if (this.二班时长>0){
this.产能+=this.二班时长*Constant.设备产能.抛丸01.get二班设备产能()/7.0;
}
this.设备.values().forEach(设备->{
设备.修正工作量(this.白班时长,this.二班时长);
this.产能+=设备.get产能();
});
}
@Override
public void 占用资源(double 所需产能) {
super.占用资源(1.0);

@ -18,14 +18,13 @@ public class 工序03理料 extends 工序产能 {
@Override
public void 计算工作量() {
this.产能=0;
if (this.白班时长>0){
this.产能+=this.白班时长*Constant.设备产能.理料01.get白班设备产能()/7.0;
}
if (this.二班时长>0){
this.产能+=this.二班时长*Constant.设备产能.理料01.get二班设备产能()/7.0;
}
this.设备.values().forEach(设备->{
设备.修正工作量(this.白班时长,this.二班时长);
this.产能+=设备.get产能();
});
}
@Override
public void 占用资源(double 所需产能) {
super.占用资源(所需产能);

@ -19,14 +19,13 @@ public class 工序04划线 extends 工序产能 {
@Override
public void 计算工作量() {
this.产能=0;
if (this.白班时长>0){
this.产能+=this.白班时长*Constant.设备产能.划线01.get白班设备产能()/7.0;
}
if (this.二班时长>0){
this.产能+=this.二班时长*Constant.设备产能.划线01.get二班设备产能()/7.0;
}
this.设备.values().forEach(设备->{
设备.修正工作量(this.白班时长,this.二班时长);
this.产能+=设备.get产能();
});
}
@Override
public void 占用资源(double 所需产能) {
super.占用资源(所需产能);

@ -1,16 +1,23 @@
package com.dsic.gj_erp.pc.dto.gx;
import com.dsic.gj_erp.pc.Constant;
import com.dsic.gj_erp.pc.dto.data.Bom;
import com.dsic.gj_erp.pc.dto.工序产能;
import com.dsic.gj_erp.pc.dto.设备;
import lombok.Getter;
import lombok.Setter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.Optional;
@Getter
@Setter
public class 工序05切割 extends 工序产能 {
private static final Logger log = LoggerFactory.getLogger(工序05切割.class);
public 工序05切割(Map<String, 设备> _设备) {
super(Constant.工序.切割,_设备);
}
@ -24,6 +31,30 @@ public class 工序05切割 extends 工序产能 {
});
}
@Override
public void 占用设备(String 占用源,double 所需产能, Bom bom){
if (!bom.判断是否为可识别跨位和切割设备的套料图()){
this.强占设备(bom.getTzbh(),1,bom);
return;
}
Optional<设备> 可占用设备 = this.获取可占用设备(bom.获取套料图分类码(),所需产能);
if (!可占用设备.isPresent()){
log.info("强占:{}",bom);
bom.超出工序产能(Constant.工序.切割);
this.强占设备(bom.getTzbh(),1,bom);
}
可占用设备.ifPresent(it->{
it.占用设备(所需产能);
it.占用设备(bom);
});
}
@Override
public Optional<设备> 获取可占用设备(String 套料图分类码,double 所需产能){
return this.设备.values().stream()
.filter(item->item.getKey().contains(套料图分类码)&&item.get占用()+所需产能<=this.产能).findFirst();
}
@Override
public void 占用资源(double 所需产能) {
super.占用资源(所需产能);

@ -18,14 +18,13 @@ public class 工序07坡口 extends 工序产能 {
@Override
public void 计算工作量() {
this.产能=0;
if (this.白班时长>0){
this.产能+=this.白班时长*Constant.设备产能.坡口01.get白班设备产能()/7.0;
}
if (this.二班时长>0){
this.产能+=this.二班时长*Constant.设备产能.坡口01.get二班设备产能()/7.0;
}
this.设备.values().forEach(设备->{
设备.修正工作量(this.白班时长,this.二班时长);
this.产能+=设备.get产能();
});
}
@Override
public void 占用资源(double 所需产能) {
super.占用资源(所需产能);

@ -18,14 +18,13 @@ public class 工序08曲面 extends 工序产能 {
@Override
public void 计算工作量() {
this.产能=0;
if (this.白班时长>0){
this.产能+=this.白班时长*Constant.设备产能.曲加工01.get白班设备产能()/7.0;
}
if (this.二班时长>0){
this.产能+=this.二班时长*Constant.设备产能.曲加工01.get二班设备产能()/7.0;
}
this.设备.values().forEach(设备->{
设备.修正工作量(this.白班时长,this.二班时长);
this.产能+=设备.get产能();
});
}
@Override
public void 占用资源(double 所需产能) {
super.占用资源(所需产能);

@ -11,6 +11,7 @@ import java.util.Map;
@Getter
@Setter
public class 工序09打磨 extends 工序产能 {
public 工序09打磨(Map<String, 设备> _设备) {
super(Constant.工序.打磨,_设备);
}
@ -18,12 +19,10 @@ public class 工序09打磨 extends 工序产能 {
@Override
public void 计算工作量() {
this.产能=0;
if (this.白班时长>0){
this.产能+=this.白班时长*Constant.设备产能.打磨01.get白班设备产能()/7.0;
}
if (this.二班时长>0){
this.产能+=this.二班时长*Constant.设备产能.打磨01.get二班设备产能()/7.0;
}
this.设备.values().forEach(设备->{
设备.修正工作量(this.白班时长,this.二班时长);
this.产能+=设备.get产能();
});
}
@Override

@ -18,14 +18,13 @@ public class 工序10型材 extends 工序产能 {
@Override
public void 计算工作量() {
this.产能=0;
if (this.白班时长>0){
this.产能+=this.白班时长*Constant.设备产能.型材01.get白班设备产能()/7.0;
}
if (this.二班时长>0){
this.产能+=this.二班时长*Constant.设备产能.型材01.get二班设备产能()/7.0;
}
this.设备.values().forEach(设备->{
设备.修正工作量(this.白班时长,this.二班时长);
this.产能+=设备.get产能();
});
}
@Override
public void 占用资源(double 所需产能) {
super.占用资源(所需产能);

@ -18,14 +18,13 @@ public class 工序21自由边处理 extends 工序产能 {
@Override
public void 计算工作量() {
this.产能=0;
if (this.白班时长>0){
this.产能+=this.白班时长*Constant.设备产能.型材01.get白班设备产能()/7.0;
}
if (this.二班时长>0){
this.产能+=this.二班时长*Constant.设备产能.型材01.get二班设备产能()/7.0;
}
this.设备.values().forEach(设备->{
设备.修正工作量(this.白班时长,this.二班时长);
this.产能+=设备.get产能();
});
}
@Override
public void 占用资源(double 所需产能) {
super.占用资源(所需产能);

@ -18,14 +18,13 @@ public class 工序31光电 extends 工序产能 {
@Override
public void 计算工作量() {
this.产能=0;
if (this.白班时长>0){
this.产能+=this.白班时长*Constant.设备产能.型材01.get白班设备产能()/7.0;
}
if (this.二班时长>0){
this.产能+=this.二班时长*Constant.设备产能.型材01.get二班设备产能()/7.0;
}
this.设备.values().forEach(设备->{
设备.修正工作量(this.白班时长,this.二班时长);
this.产能+=设备.get产能();
});
}
@Override
public void 占用资源(double 所需产能) {
super.占用资源(所需产能);

@ -13,4 +13,14 @@ public class 设备01上料 extends 设备 {
public 设备01上料(Constant.设备产能 _设备产能) {
super(_设备产能);
}
@Override
public void 修正工作量(double 白班时长, double 二班时长){
this.产能=this.双班合计产能;
}
@Override
public boolean 判断设备是否可以被占用(double 产量){
return this.占用+产量>this.产能;
}
}

@ -13,4 +13,14 @@ public class 设备02抛丸 extends 设备 {
public 设备02抛丸(Constant.设备产能 _设备产能) {
super(_设备产能);
}
@Override
public void 修正工作量(double 白班时长, double 二班时长){
this.产能=this.双班合计产能;
}
@Override
public boolean 判断设备是否可以被占用(double 产量){
return this.占用+产量>this.产能;
}
}

@ -13,4 +13,14 @@ public class 设备03理料 extends 设备 {
public 设备03理料(Constant.设备产能 _设备产能) {
super(_设备产能);
}
@Override
public void 修正工作量(double 白班时长, double 二班时长){
this.产能=this.双班合计产能;
}
@Override
public boolean 判断设备是否可以被占用(double 产量){
return this.占用+产量>this.产能;
}
}

@ -13,4 +13,14 @@ public class 设备04划线 extends 设备 {
public 设备04划线(Constant.设备产能 _设备产能) {
super(_设备产能);
}
@Override
public void 修正工作量(double 白班时长, double 二班时长){
this.产能=this.双班合计产能;
}
@Override
public boolean 判断设备是否可以被占用(double 产量){
return this.占用+产量>this.产能;
}
}

@ -22,14 +22,13 @@ public class 设备05切割 extends 设备 {
super(_设备产能);
}
// @Override
// public void 修正工作量(double 白班时长, double 二班时长) {
// this.白班时长=白班时长;
// this.二班时长=二班时长;
// this.修正产能();
// }
//
// public void 修正产能(){
// this.产能=this.白班设备产能*this.白班时长+this.二班设备产能*this.二班时长;
// }
@Override
public void 修正工作量(double 白班时长, double 二班时长){
this.产能=this.双班合计产能;
}
@Override
public boolean 判断设备是否可以被占用(double 产量){
return this.占用+产量>this.产能;
}
}

@ -13,4 +13,14 @@ public class 设备07坡口 extends 设备 {
public 设备07坡口(Constant.设备产能 _设备产能) {
super(_设备产能);
}
@Override
public void 修正工作量(double 白班时长, double 二班时长){
this.产能=this.双班合计产能;
}
@Override
public boolean 判断设备是否可以被占用(double 产量){
return this.占用+产量>this.产能;
}
}

@ -13,4 +13,14 @@ public class 设备08曲面 extends 设备 {
public 设备08曲面(Constant.设备产能 _设备产能) {
super(_设备产能);
}
@Override
public void 修正工作量(double 白班时长, double 二班时长){
this.产能=this.双班合计产能;
}
@Override
public boolean 判断设备是否可以被占用(double 产量){
return this.占用+产量>this.产能;
}
}

@ -13,4 +13,14 @@ public class 设备09打磨 extends 设备 {
public 设备09打磨(Constant.设备产能 _设备产能) {
super(_设备产能);
}
@Override
public void 修正工作量(double 白班时长, double 二班时长){
this.产能=this.双班合计产能;
}
@Override
public boolean 判断设备是否可以被占用(double 产量){
return this.占用+产量>this.产能;
}
}

@ -13,4 +13,14 @@ public class 设备10型材 extends 设备 {
public 设备10型材(Constant.设备产能 _设备产能) {
super(_设备产能);
}
@Override
public void 修正工作量(double 白班时长, double 二班时长){
this.产能=this.双班合计产能;
}
@Override
public boolean 判断设备是否可以被占用(double 产量){
return this.占用+产量>this.产能;
}
}

@ -13,4 +13,14 @@ public class 设备21自由边处理 extends 设备 {
public 设备21自由边处理(Constant.设备产能 _设备产能) {
super(_设备产能);
}
@Override
public void 修正工作量(double 白班时长, double 二班时长){
this.产能=this.双班合计产能;
}
@Override
public boolean 判断设备是否可以被占用(double 产量){
return this.占用+产量>this.产能;
}
}

@ -13,4 +13,14 @@ public class 设备31光电 extends 设备 {
public 设备31光电(Constant.设备产能 _设备产能) {
super(_设备产能);
}
@Override
public void 修正工作量(double 白班时长, double 二班时长){
this.产能=this.双班合计产能;
}
@Override
public boolean 判断设备是否可以被占用(double 产量){
return this.占用+产量>this.产能;
}
}

@ -102,7 +102,6 @@ public abstract class 套料图工序 implements 套料图工序接口 {
public void run(AtomicBoolean atomicBoolean) {
if (!this.订货()){
// System.out.println(String.format("船号:%s,批量:%s,未订货",this.bom.getDcch(),this.bom.getPl()));
bom.没有订货();
}
@ -191,11 +190,12 @@ public abstract class 套料图工序 implements 套料图工序接口 {
资源 _资源 = 提取资源(dateTime);
try {
if (_资源.占用资源(_工序,this.bom,需求数量)){
this.bom.set所在资源(_资源);
// this.bom.set所在资源(_资源);
this.bom.get已排工序().add(0,_工序);
}
}catch (Exception e){
e.printStackTrace();
throw e;
}
return _资源;
@ -208,7 +208,7 @@ public abstract class 套料图工序 implements 套料图工序接口 {
AtomicBoolean 占用成功=new AtomicBoolean(false);
try {
if (_资源.占用资源(_工序,this.bom,需求数量)){
this.bom.set所在资源(_资源);
// this.bom.set所在资源(_资源);
this.bom.get已排工序().add(0,_工序);
占用成功.set(true);
}

@ -69,13 +69,12 @@ public abstract class 工序产能 implements 工序排产处理接口 {
.findFirst();
}
public Optional<设备> 获取可占用设备(double 所需产能){
public Optional<设备> 获取可占用设备(String 套料图分类码,double 所需产能){
return this.设备.values().stream().findAny();
}
public boolean 判断设备是否可以占用(String 设备编号,double 所需产能){
设备 _设备 = this.设备.get(设备编号);
return _设备.占用+所需产能<=_设备.产能;
public Optional<设备> 获取可占用设备(double 所需产能){
return this.设备.values().stream().findAny();
}
public boolean 判断是否可以占用(double 所需产能){
@ -87,7 +86,7 @@ public abstract class 工序产能 implements 工序排产处理接口 {
}
public void 占用资源(String 占用源){
this.资源占用图纸表.add(占用源);
//this.资源占用图纸表.add(占用源);
}
public void 占用设备(String 占用源,double 所需产能, Bom bom){
@ -97,6 +96,7 @@ public abstract class 工序产能 implements 工序排产处理接口 {
it.占用设备(bom);
});
}
public void 强占设备(String 占用源,double 所需产能, Bom bom){
Optional<设备> _设备 = this.设备.values().stream().findAny();
_设备.ifPresent(it->{

@ -1,5 +1,8 @@
package com.dsic.gj_erp.pc.dto;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.dsic.gj_erp.pc.Constant;
import com.dsic.gj_erp.pc.dto.data.Bom;
import com.dsic.gj_erp.pc.service.设备接口;
@ -16,10 +19,12 @@ public abstract class 设备 implements 设备接口 {
protected String 设备名称;
protected double 白班设备产能;
protected double 二班设备产能;
protected double 双班合计产能;
protected double 产能;
protected volatile double 占用=0.0;
protected ConcurrentLinkedDeque<String> 资源占用图纸表;
protected ConcurrentLinkedDeque<Bom> 资源占用图表;
protected String key;
@Override
public void 修正工作量(double 白班时长, double 二班时长) {
@ -31,6 +36,11 @@ public abstract class 设备 implements 设备接口 {
this.产能+=二班时长*二班设备产能/7.0;
}
}
public boolean 判断设备是否可以被占用(double 产量){
return false;
}
@Override
public void 占用设备(double 所需产能) {
this.占用+=所需产能;
@ -52,17 +62,25 @@ public abstract class 设备 implements 设备接口 {
this.设备名称= _设备产能.get设备名称();
this.白班设备产能= _设备产能.get白班设备产能();
this.二班设备产能= _设备产能.get二班设备产能();
this.双班合计产能=_设备产能.get双班合计产能();
this.key=_设备产能.get套料图编码();
this.资源占用图纸表=new ConcurrentLinkedDeque<>();
this.资源占用图表=new ConcurrentLinkedDeque<>();
}
public 设备(Constant.设备产能 _设备产能){
this.设备编号= _设备产能.设备编号;
this.设备名称= _设备产能.设备名称;
this.白班设备产能= _设备产能.白班设备产能;
this.二班设备产能= _设备产能.二班设备产能;
this.双班合计产能=_设备产能.get双班合计产能();
this.资源占用图纸表=new ConcurrentLinkedDeque<>();
this.资源占用图表=new ConcurrentLinkedDeque<>();
}
public static void main(String[] args) {
int d=-7;
DateTime offset = DateUtil.date().offset(DateField.DAY_OF_YEAR, -d);
System.out.println(offset.toDateStr());
}
}

@ -2,8 +2,10 @@ package com.dsic.gj_erp.pc.dto;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.dsic.gj_erp.pc.Constant;
import com.dsic.gj_erp.pc.dto.data.Bom;
import com.google.common.util.concurrent.AtomicDouble;
import lombok.Getter;
import lombok.Setter;
@ -31,6 +33,19 @@ public class 资源 {
});
}
public boolean 判断切割设备是否可以被占用(Map<String, AtomicDouble> 切割各设备需求量){
工序产能 工序产能 = 工序产能MAP.get(Constant.工序.切割);
Map<String, 设备> 设备 = 工序产能.get设备();
AtomicBoolean flag=new AtomicBoolean(true);
设备.values().forEach(it->{
AtomicDouble 产量=切割各设备需求量.get(it.getKey());
if (产量!=null&&it.get占用()+产量.get()>it.产能){
flag.set(false);
}
});
return flag.get();
}
public boolean 判断工序是否可以被占用(Constant.工序 _工序 ,double 产能消耗){
工序产能 工序产能 = 工序产能MAP.get(_工序);
AtomicBoolean atomicBoolean = new AtomicBoolean(false);
@ -44,8 +59,14 @@ public class 资源 {
public boolean 占用资源(Constant.工序 工序, Bom bom, double 产能消耗){
AtomicBoolean atomicBoolean = new AtomicBoolean(false);
if (bom.getTzbh().equals("B020N4PX004")){
System.out.println(111);
}
工序产能 工序产能 = 工序产能MAP.get(工序);
Optional.ofNullable(工序产能).ifPresent(it->{
if (it.产能==0){
return;
}
if (!it.判断是否可以占用(产能消耗)){
bom.超出工序产能(工序);
}

@ -1,5 +1,7 @@
package com.dsic.gj_erp.pc.service;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@ -51,8 +53,12 @@ public class 三月滚动接口 {
Map<String, List<DmSygdMx>> collect = mxList.stream().collect(Collectors.groupingBy(item -> item.getDcCh() + item.getDcPl() + item.getTzbh()));
Manager.资源池.values().forEach(_资源->{
_资源.get工序产能MAP().values().forEach(_工序产能->{
DateTime from = DateUtil.parse(begin, "yyyy/MM/dd");
DateTime to = DateUtil.parse(end, "yyyy/MM/dd");
Manager.资源池.values().parallelStream()
.filter(_资源->DateUtil.isIn(_资源.get_date(),from,to))
.forEach(_资源->{_资源.get工序产能MAP().values().forEach(_工序产能->{
_工序产能.get设备().values().forEach(_设备->{
_设备.get资源占用图表().parallelStream().forEach(_bom->{
List<DmSygdMx> dmSygdMxes = collect.get(_bom.getDcch() + _bom.getPl() + _bom.getTzbh());

@ -3,6 +3,7 @@ package com.dsic.gj_erp.pc.service;
import com.dsic.gj_erp.pc.dto.data.Bom;
public interface 工序排产处理接口 {
void 修正工作量(double 白班时长,double 二班时长);

@ -20,4 +20,6 @@ public interface 设备接口 {
void 占用设备(String 占用源);
void 占用设备(Bom bom);
boolean 判断设备是否可以被占用(double 产量);
}

@ -17,15 +17,14 @@ public class 排产 {
List<排产结果> list;
public static void execute(@NotNull String from, @NotNull String to) {
排产 _排产 = 排产.of(from, to);
Manager.排产 = _排产;
Manager.排产 = 排产.of(from, to);
Manager.from = from;
Manager.to = to;
DataFactory.加载工厂日历();
DataFactory.加载套料图工序对应关系();
DataFactory.加载设备信息();
DataFactory.创建产能资源池();
DataFactory.排产3();
DataFactory.排产4();
}
private static 排产 of(@NotNull String from, @NotNull String to){
@ -34,6 +33,7 @@ public class 排产 {
排产.to = to;
排产.complete = false;
排产.list = new ArrayList<>();
Manager.排产 = 排产;
return Manager.排产;
}

@ -15,5 +15,7 @@ public class 设备产能 {
private double 二班设备产能;
private double 双班合计产能;
private boolean 禁用;
private String 跨位;
private String 套料图编码;
}

@ -8,7 +8,6 @@ import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsic.gj_erp.bean.jcsj.DmBom;
import com.dsic.gj_erp.bean.jhgk.DmSygdMx;
import com.dsic.gj_erp.bean.jhgk.DmSygdxq;
import com.dsic.gj_erp.bean.jhgk.DmSygdxqOld;
@ -131,7 +130,11 @@ public class DmSygdxqServiceImpl extends ServiceImpl<DmSygdxqMapper, DmSygdxq> i
@Override
public List<DmSygdxq> getXqWithBom(String from, String to) {
return baseMapper.getXqWithBom(from,to);
return t(from,to,"","");
}
private List<DmSygdxq> t(String from, String to,String dcch,String pl){
return baseMapper.getXqWithBom(from,to,dcch,pl);
}
//零件信息

@ -54,6 +54,12 @@
dm_sygdxq xq left join dm_bom bom on bom.dcch = xq.DC_CH and bom.pl = xq.DC_PL and bom.fd = xq.DC_FD
where
xq.xzglxq between #{from} and #{to}
<if test="dcch!=null and dcch!=''">
and xq.DC_CH=#{dcch}
</if>
<if test="pl!=null and pl!=''">
and bom.pl=#{pl}
</if>
) a
where a.rn=1
order by a.xzglxq

Loading…
Cancel
Save