修复采购和集成酸轧细节
This commit is contained in:
@@ -13,7 +13,6 @@ import com.klp.common.utils.poi.ExcelUtil;
|
||||
import com.klp.erp.domain.bo.ErpPurchasePlanAuditBo;
|
||||
import com.klp.erp.domain.bo.ErpPurchasePlanBo;
|
||||
import com.klp.erp.domain.vo.ErpContractOptionVo;
|
||||
import com.klp.erp.domain.vo.ErpPurchasePlanDeliveryBatchVo;
|
||||
import com.klp.erp.domain.vo.ErpPurchasePlanDeliveryVo;
|
||||
import com.klp.erp.domain.vo.ErpPurchasePlanItemVo;
|
||||
import com.klp.erp.domain.vo.ErpPurchasePlanVo;
|
||||
@@ -149,19 +148,13 @@ public class ErpPurchasePlanController extends BaseController {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/** 某计划的到货上传批次(每次上传一条,可回看) */
|
||||
@GetMapping("/{planId}/deliveryBatches")
|
||||
public R<List<ErpPurchasePlanDeliveryBatchVo>> deliveryBatches(@PathVariable Long planId) {
|
||||
return R.ok(iErpPurchasePlanService.queryDeliveryBatches(planId));
|
||||
/** 厂商历史记忆(手填自动补全) */
|
||||
@GetMapping("/manufacturers")
|
||||
public R<List<String>> manufacturers(@RequestParam(value = "keyword", required = false) String keyword) {
|
||||
return R.ok(iErpPurchasePlanService.queryManufacturers(keyword));
|
||||
}
|
||||
|
||||
/** 某批次的到货明细 */
|
||||
@GetMapping("/deliveryBatch/{batchId}")
|
||||
public R<List<ErpPurchasePlanDeliveryVo>> deliveryByBatch(@PathVariable Long batchId) {
|
||||
return R.ok(iErpPurchasePlanService.queryDeliveryListByBatch(batchId));
|
||||
}
|
||||
|
||||
/** 到货记录页左侧:审核通过的计划分页 */
|
||||
/** 到货记录页左侧:审核通过的合同分页 */
|
||||
@GetMapping("/deliveryPlans")
|
||||
public TableDataInfo<ErpPurchasePlanVo> deliveryPlans(@RequestParam(value = "keyword", required = false) String keyword,
|
||||
PageQuery pageQuery) {
|
||||
|
||||
@@ -57,12 +57,18 @@ public class ErpPurchasePlan extends BaseEntity {
|
||||
/** 已到货重量(T) = Σ到货卷(WMS已确认)单卷重量 */
|
||||
private BigDecimal arrivedWeight;
|
||||
|
||||
/** 计划要求总数量(卷/件) = Σ明细数量 */
|
||||
/** 要求项数 = 明细行数 */
|
||||
private Integer planQty;
|
||||
|
||||
/** 已到货卷数 = WMS确认到货的上传卷数 */
|
||||
private Integer arrivedCount;
|
||||
|
||||
/** 在途卷数 = 钢卷表存在但 data_type=10 的上传卷数 */
|
||||
private Integer inTransitCount;
|
||||
|
||||
/** 在途重量(T) */
|
||||
private BigDecimal inTransitWeight;
|
||||
|
||||
/** 删除标志 */
|
||||
@TableLogic
|
||||
private String delFlag;
|
||||
|
||||
@@ -33,9 +33,12 @@ public class ErpPurchasePlanDelivery extends BaseEntity {
|
||||
/** 关联上传批次ID */
|
||||
private Long batchId;
|
||||
|
||||
/** 是否WMS已确认到货: 1-是 0-否(卷号在钢卷表查不到或为占位类型) */
|
||||
/** 是否WMS已确认到货: 1-是 0-否(卷号在钢卷表存在且 data_type<>10) */
|
||||
private Integer arrived;
|
||||
|
||||
/** 是否在途: 1-是(卷号在钢卷表存在但 data_type=10) 0-否 */
|
||||
private Integer inTransit;
|
||||
|
||||
/** 日期 */
|
||||
private Date arrivalDate;
|
||||
|
||||
|
||||
@@ -29,6 +29,12 @@ public class ErpPurchasePlanItem extends BaseEntity {
|
||||
/** 关联计划ID */
|
||||
private Long planId;
|
||||
|
||||
/** 规格 */
|
||||
private String spec;
|
||||
|
||||
/** 厂商(手填,带历史记忆) */
|
||||
private String manufacturer;
|
||||
|
||||
/** 产品(如热轧卷板) */
|
||||
private String productType;
|
||||
|
||||
|
||||
@@ -22,6 +22,12 @@ public class ErpPurchasePlanItemBo extends BaseEntity {
|
||||
/** 关联计划ID */
|
||||
private Long planId;
|
||||
|
||||
/** 规格 */
|
||||
private String spec;
|
||||
|
||||
/** 厂商(手填,带历史记忆) */
|
||||
private String manufacturer;
|
||||
|
||||
/** 产品(如热轧卷板) */
|
||||
private String productType;
|
||||
|
||||
|
||||
@@ -31,6 +31,9 @@ public class ErpPurchasePlanDeliveryVo implements Serializable {
|
||||
/** 是否WMS已确认到货: 1-是 0-否 */
|
||||
private Integer arrived;
|
||||
|
||||
/** 是否在途: 1-是 0-否 */
|
||||
private Integer inTransit;
|
||||
|
||||
@ExcelProperty(value = "日期")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private Date arrivalDate;
|
||||
|
||||
@@ -24,6 +24,12 @@ public class ErpPurchasePlanItemVo implements Serializable {
|
||||
|
||||
private Long planId;
|
||||
|
||||
@ExcelProperty(value = "规格")
|
||||
private String spec;
|
||||
|
||||
@ExcelProperty(value = "厂商")
|
||||
private String manufacturer;
|
||||
|
||||
@ExcelProperty(value = "产品")
|
||||
private String productType;
|
||||
|
||||
|
||||
@@ -59,21 +59,24 @@ public class ErpPurchasePlanVo implements Serializable {
|
||||
@ExcelProperty(value = "已到货重量(T)")
|
||||
private BigDecimal arrivedWeight;
|
||||
|
||||
/** 计划要求总数量(卷/件) */
|
||||
/** 要求项数(明细行数) */
|
||||
private Integer planQty;
|
||||
|
||||
/** 已到货卷数 */
|
||||
private Integer arrivedCount;
|
||||
|
||||
/** 在途卷数 */
|
||||
private Integer inTransitCount;
|
||||
|
||||
/** 在途重量(T) */
|
||||
private BigDecimal inTransitWeight;
|
||||
|
||||
@ExcelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
/** 到货进度-按重量(0-100) = 已到货重量/计划要求总重量 */
|
||||
/** 到货进度-按重量(0-100) = 已到货重量/要求总重量 */
|
||||
private BigDecimal progress;
|
||||
|
||||
/** 到货进度-按卷数(0-100) = 已到货卷数/计划要求总数量 */
|
||||
private BigDecimal progressQty;
|
||||
|
||||
/** 明细行 */
|
||||
private List<ErpPurchasePlanItemVo> items;
|
||||
|
||||
|
||||
@@ -51,4 +51,14 @@ public interface ErpPurchasePlanMapper extends BaseMapperPlus<ErpPurchasePlanMap
|
||||
* 用于判定上传到货行的卷号是否已实际到货入库。
|
||||
*/
|
||||
List<String> selectExistingSupplierCoilNos(@Param("coilNos") Collection<String> coilNos);
|
||||
|
||||
/**
|
||||
* 在途卷号:WMS 钢卷表中存在但 data_type=10(在途)的厂家卷号集合。
|
||||
*/
|
||||
List<String> selectInTransitSupplierCoilNos(@Param("coilNos") Collection<String> coilNos);
|
||||
|
||||
/**
|
||||
* 厂商历史记忆:已保存过的厂商去重(可按关键字过滤),用于手填自动补全。
|
||||
*/
|
||||
List<String> selectDistinctManufacturers(@Param("kw") String kw);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import com.klp.erp.domain.bo.ErpPurchasePlanAuditBo;
|
||||
import com.klp.erp.domain.bo.ErpPurchasePlanBo;
|
||||
import com.klp.erp.domain.vo.ErpContractOptionVo;
|
||||
import com.klp.erp.domain.vo.ErpPurchasePlanAuditLogVo;
|
||||
import com.klp.erp.domain.vo.ErpPurchasePlanDeliveryBatchVo;
|
||||
import com.klp.erp.domain.vo.ErpPurchasePlanDeliveryVo;
|
||||
import com.klp.erp.domain.vo.ErpPurchasePlanItemVo;
|
||||
import com.klp.erp.domain.vo.ErpPurchasePlanVo;
|
||||
@@ -66,16 +65,13 @@ public interface IErpPurchasePlanService {
|
||||
*/
|
||||
Map<String, Object> importDelivery(Long planId, InputStream inputStream, String fileName, String operator);
|
||||
|
||||
/** 查询某计划的到货明细(matched 标记是否与明细卷号匹配) */
|
||||
/** 查询某计划的到货明细(仅最新一次上传,含到货/在途标记) */
|
||||
List<ErpPurchasePlanDeliveryVo> queryDeliveryList(Long planId);
|
||||
|
||||
/** 某计划下指定批次的到货明细 */
|
||||
List<ErpPurchasePlanDeliveryVo> queryDeliveryListByBatch(Long batchId);
|
||||
/** 厂商历史记忆(去重,可按关键字过滤),用于手填自动补全 */
|
||||
List<String> queryManufacturers(String keyword);
|
||||
|
||||
/** 某计划的到货上传批次(最新在前) */
|
||||
List<ErpPurchasePlanDeliveryBatchVo> queryDeliveryBatches(Long planId);
|
||||
|
||||
/** 到货记录页左侧:审核通过的计划分页(含合同号、明细数、进度) */
|
||||
/** 到货记录页左侧:审核通过的合同分页(含合同号、出卖方、进度) */
|
||||
TableDataInfo<ErpPurchasePlanVo> queryDeliveryPlanPage(String keyword, PageQuery pageQuery);
|
||||
|
||||
/** 删除到货明细,并刷新进度 */
|
||||
|
||||
@@ -13,7 +13,6 @@ import com.klp.common.utils.StringUtils;
|
||||
import com.klp.erp.domain.ErpPurchasePlan;
|
||||
import com.klp.erp.domain.ErpPurchasePlanContractRel;
|
||||
import com.klp.erp.domain.ErpPurchasePlanDelivery;
|
||||
import com.klp.erp.domain.ErpPurchasePlanDeliveryBatch;
|
||||
import com.klp.erp.domain.ErpPurchasePlanItem;
|
||||
import com.klp.erp.domain.ErpPurchasePlanAuditLog;
|
||||
import com.klp.erp.domain.bo.ErpPurchasePlanAuditBo;
|
||||
@@ -21,13 +20,11 @@ import com.klp.erp.domain.bo.ErpPurchasePlanBo;
|
||||
import com.klp.erp.domain.bo.ErpPurchasePlanItemBo;
|
||||
import com.klp.erp.domain.vo.ErpContractOptionVo;
|
||||
import com.klp.erp.domain.vo.ErpPurchasePlanAuditLogVo;
|
||||
import com.klp.erp.domain.vo.ErpPurchasePlanDeliveryBatchVo;
|
||||
import com.klp.erp.domain.vo.ErpPurchasePlanDeliveryImportVo;
|
||||
import com.klp.erp.domain.vo.ErpPurchasePlanDeliveryVo;
|
||||
import com.klp.erp.domain.vo.ErpPurchasePlanItemVo;
|
||||
import com.klp.erp.domain.vo.ErpPurchasePlanVo;
|
||||
import com.klp.erp.mapper.ErpPurchasePlanContractRelMapper;
|
||||
import com.klp.erp.mapper.ErpPurchasePlanDeliveryBatchMapper;
|
||||
import com.klp.erp.mapper.ErpPurchasePlanDeliveryMapper;
|
||||
import com.klp.erp.mapper.ErpPurchasePlanItemMapper;
|
||||
import com.klp.erp.mapper.ErpPurchasePlanAuditLogMapper;
|
||||
@@ -46,7 +43,6 @@ import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -73,7 +69,6 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService {
|
||||
private final ErpPurchasePlanItemMapper itemMapper;
|
||||
private final ErpPurchasePlanContractRelMapper relMapper;
|
||||
private final ErpPurchasePlanDeliveryMapper deliveryMapper;
|
||||
private final ErpPurchasePlanDeliveryBatchMapper deliveryBatchMapper;
|
||||
private final ErpPurchasePlanAuditLogMapper auditLogMapper;
|
||||
|
||||
@Override
|
||||
@@ -167,7 +162,7 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService {
|
||||
add.setAuditStatus(AUDIT_DRAFT); // 新建为「待送审」,需手动送审后才进入审核池
|
||||
add.setArrivedWeight(BigDecimal.ZERO);
|
||||
add.setPlanWeight(sumItemWeight(bo.getItems()));
|
||||
add.setPlanQty(sumItemQty(bo.getItems()));
|
||||
add.setPlanQty(bo.getItems() == null ? 0 : bo.getItems().size());
|
||||
add.setArrivedCount(0);
|
||||
if (baseMapper.insert(add) <= 0) {
|
||||
return false;
|
||||
@@ -192,7 +187,7 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService {
|
||||
update.setPlanNo(bo.getPlanNo());
|
||||
}
|
||||
update.setPlanWeight(sumItemWeight(bo.getItems()));
|
||||
update.setPlanQty(sumItemQty(bo.getItems()));
|
||||
update.setPlanQty(bo.getItems() == null ? 0 : bo.getItems().size());
|
||||
baseMapper.updateById(update);
|
||||
// 覆盖式重写明细与合同关联
|
||||
itemMapper.delete(Wrappers.lambdaQuery(ErpPurchasePlanItem.class)
|
||||
@@ -242,13 +237,6 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService {
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
}
|
||||
|
||||
private int sumItemQty(List<ErpPurchasePlanItemBo> items) {
|
||||
if (items == null) {
|
||||
return 0;
|
||||
}
|
||||
return items.stream().mapToInt(i -> i.getQuantity() == null ? 0 : i.getQuantity()).sum();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
@@ -341,31 +329,7 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService {
|
||||
if (valid.isEmpty()) {
|
||||
throw new ServiceException("未解析到有效到货数据,请检查文件内容或列名是否与模板一致");
|
||||
}
|
||||
// 2) 牌号校验:到货表里的牌号必须都在本计划「采购要求」的牌号范围内
|
||||
List<ErpPurchasePlanItem> planItems = itemMapper.selectList(Wrappers.lambdaQuery(ErpPurchasePlanItem.class)
|
||||
.eq(ErpPurchasePlanItem::getPlanId, planId));
|
||||
Set<String> reqGrades = planItems.stream()
|
||||
.map(it -> normCoil(it.getGrade()))
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.collect(Collectors.toSet());
|
||||
if (!reqGrades.isEmpty()) {
|
||||
Set<String> badGrades = new LinkedHashSet<>();
|
||||
for (ErpPurchasePlanDeliveryImportVo r : valid) {
|
||||
String g = normCoil(r.getGrade());
|
||||
if (StringUtils.isBlank(g)) {
|
||||
badGrades.add("(空牌号)");
|
||||
} else if (!reqGrades.contains(g)) {
|
||||
badGrades.add(r.getGrade().trim());
|
||||
}
|
||||
}
|
||||
if (!badGrades.isEmpty()) {
|
||||
String allow = planItems.stream().map(ErpPurchasePlanItem::getGrade)
|
||||
.filter(StringUtils::isNotBlank).map(String::trim).distinct().collect(Collectors.joining("、"));
|
||||
throw new ServiceException("到货表中的牌号 [" + String.join("、", badGrades)
|
||||
+ "] 不在本计划采购要求的牌号范围内(仅允许:" + allow + "),请核对后重新上传");
|
||||
}
|
||||
}
|
||||
// 3) kg→t 单位判定(文件级:单卷重量最大值超阈值视为 kg)
|
||||
// 2) kg→t 单位判定(文件级:单卷重量最大值超阈值视为 kg)
|
||||
BigDecimal maxCoil = valid.stream()
|
||||
.map(ErpPurchasePlanDeliveryImportVo::getCoilWeight)
|
||||
.filter(w -> w != null)
|
||||
@@ -373,29 +337,26 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService {
|
||||
.orElse(BigDecimal.ZERO);
|
||||
boolean kgConverted = maxCoil.compareTo(KG_THRESHOLD) > 0;
|
||||
|
||||
// 4) 卷号去 WMS 钢卷表校验:存在且 data_type<>10 即视为已实际到货入库
|
||||
// 3) 卷号去 WMS 钢卷表分类:存在且 data_type<>10=已到货;data_type=10=在途;查不到=未到
|
||||
List<String> uploadCoilNos = valid.stream()
|
||||
.map(ErpPurchasePlanDeliveryImportVo::getCoilNo)
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.map(String::trim)
|
||||
.filter(StringUtils::isNotBlank).map(String::trim)
|
||||
.collect(Collectors.toList());
|
||||
Set<String> wmsArrivedSet = uploadCoilNos.isEmpty() ? new HashSet<>()
|
||||
: baseMapper.selectExistingSupplierCoilNos(uploadCoilNos).stream()
|
||||
.map(this::normCoil).collect(Collectors.toSet());
|
||||
Set<String> arrivedSet = uploadCoilNos.isEmpty() ? new HashSet<>()
|
||||
: baseMapper.selectExistingSupplierCoilNos(uploadCoilNos).stream().map(this::normCoil).collect(Collectors.toSet());
|
||||
Set<String> inTransitSet = uploadCoilNos.isEmpty() ? new HashSet<>()
|
||||
: baseMapper.selectInTransitSupplierCoilNos(uploadCoilNos).stream().map(this::normCoil).collect(Collectors.toSet());
|
||||
|
||||
// 5) 先建批次(每次上传存档,可随时回看)
|
||||
ErpPurchasePlanDeliveryBatch batch = new ErpPurchasePlanDeliveryBatch();
|
||||
batch.setPlanId(planId);
|
||||
batch.setFileName(StringUtils.isNotBlank(fileName) ? fileName : "到货表");
|
||||
deliveryBatchMapper.insert(batch);
|
||||
// 4) 覆盖式:每次上传只用最新文件,先清掉该计划旧到货记录
|
||||
deliveryMapper.delete(Wrappers.lambdaQuery(ErpPurchasePlanDelivery.class).eq(ErpPurchasePlanDelivery::getPlanId, planId));
|
||||
|
||||
// 6) 落库 + 单位换算 + WMS到货标记
|
||||
// 5) 落库 + 单位换算 + 到货/在途标记
|
||||
// 合并单元格:车号(F)几卷共用一车 → 向下填充让每卷都带车号;
|
||||
// 数量(G=整车总重)/件数(H=整车件数) 是「整车合计」,只记在该车首行(其余行留空),
|
||||
// 避免按行重复计数(用户:一共3件,不是每行3件)。
|
||||
// 数量(G=整车总重)/件数(H=整车件数) 是整车合计,只记在该车首行,不向下填充。
|
||||
String lastTruckNo = null;
|
||||
int count = 0;
|
||||
int matched = 0;
|
||||
int arrivedNum = 0;
|
||||
int transitNum = 0;
|
||||
for (ErpPurchasePlanDeliveryImportVo row : rows) {
|
||||
if (StringUtils.isNotBlank(row.getTruckNo())) {
|
||||
lastTruckNo = row.getTruckNo();
|
||||
@@ -403,20 +364,19 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService {
|
||||
if (StringUtils.isBlank(row.getCoilNo()) && row.getCoilWeight() == null) {
|
||||
continue;
|
||||
}
|
||||
boolean arrived = StringUtils.isNotBlank(row.getCoilNo()) && wmsArrivedSet.contains(normCoil(row.getCoilNo()));
|
||||
String coil = normCoil(row.getCoilNo());
|
||||
boolean arrived = !coil.isEmpty() && arrivedSet.contains(coil);
|
||||
boolean transit = !arrived && !coil.isEmpty() && inTransitSet.contains(coil);
|
||||
ErpPurchasePlanDelivery d = new ErpPurchasePlanDelivery();
|
||||
d.setPlanId(planId);
|
||||
d.setBatchId(batch.getBatchId());
|
||||
d.setArrived(arrived ? 1 : 0);
|
||||
d.setInTransit(transit ? 1 : 0);
|
||||
d.setArrivalDate(parseDate(row.getArrivalDate()));
|
||||
d.setGrade(row.getGrade());
|
||||
d.setSpec(row.getSpec());
|
||||
d.setCoilNo(row.getCoilNo());
|
||||
d.setCoilWeight(convertWeight(row.getCoilWeight(), kgConverted));
|
||||
// 车号:每卷归属的车(向下填充)
|
||||
d.setTruckNo(StringUtils.isNotBlank(row.getTruckNo()) ? row.getTruckNo() : lastTruckNo);
|
||||
// 整车总重 / 件数:整车合计,仅该车首行有值,不向下填充
|
||||
// 数量/件数 作为 String 读取以兼容合并单元格的空白/点号等占位符,在此 parse
|
||||
d.setTruckWeight(convertWeight(parseDecimal(row.getTruckWeight()), kgConverted));
|
||||
d.setPieceCount(parseInteger(row.getPieceCount()));
|
||||
d.setSalesCode(row.getSalesCode());
|
||||
@@ -424,20 +384,16 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService {
|
||||
deliveryMapper.insert(d);
|
||||
count++;
|
||||
if (arrived) {
|
||||
matched++;
|
||||
arrivedNum++;
|
||||
} else if (transit) {
|
||||
transitNum++;
|
||||
}
|
||||
}
|
||||
// 7) 汇总刷新进度
|
||||
// 6) 汇总刷新进度
|
||||
refreshProgress(planId);
|
||||
|
||||
// 8) 回填批次统计(行数、WMS确认到货卷数、上传后进度快照)
|
||||
ErpPurchasePlan after = baseMapper.selectById(planId);
|
||||
batch.setRowCount(count);
|
||||
batch.setMatchedCount(matched);
|
||||
batch.setArrivedPercent(calcPct(after.getArrivedWeight(), after.getPlanWeight()));
|
||||
deliveryBatchMapper.updateById(batch);
|
||||
|
||||
StringBuilder msg = new StringBuilder("成功导入 " + count + " 条到货记录,其中 " + matched + " 卷在钢卷表确认到货");
|
||||
int notArrived = count - arrivedNum - transitNum;
|
||||
StringBuilder msg = new StringBuilder("导入 " + count + " 条:已到 " + arrivedNum + " 卷,在途 " + transitNum + " 卷,未到 " + notArrived + " 卷");
|
||||
if (kgConverted) {
|
||||
msg.append(";检测到重量疑似按 kg 录入(最大单卷 ")
|
||||
.append(maxCoil.stripTrailingZeros().toPlainString())
|
||||
@@ -445,7 +401,8 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService {
|
||||
}
|
||||
Map<String, Object> result = new HashMap<>(6);
|
||||
result.put("count", count);
|
||||
result.put("matched", matched);
|
||||
result.put("arrived", arrivedNum);
|
||||
result.put("inTransit", transitNum);
|
||||
result.put("kgConverted", kgConverted);
|
||||
result.put("message", msg.toString());
|
||||
return result;
|
||||
@@ -508,17 +465,8 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ErpPurchasePlanDeliveryVo> queryDeliveryListByBatch(Long batchId) {
|
||||
return deliveryMapper.selectVoList(Wrappers.lambdaQuery(ErpPurchasePlanDelivery.class)
|
||||
.eq(ErpPurchasePlanDelivery::getBatchId, batchId)
|
||||
.orderByDesc(ErpPurchasePlanDelivery::getDeliveryId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ErpPurchasePlanDeliveryBatchVo> queryDeliveryBatches(Long planId) {
|
||||
return deliveryBatchMapper.selectVoList(Wrappers.lambdaQuery(ErpPurchasePlanDeliveryBatch.class)
|
||||
.eq(ErpPurchasePlanDeliveryBatch::getPlanId, planId)
|
||||
.orderByDesc(ErpPurchasePlanDeliveryBatch::getBatchId));
|
||||
public List<String> queryManufacturers(String keyword) {
|
||||
return baseMapper.selectDistinctManufacturers(keyword);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -568,27 +516,39 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService {
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.map(String::trim)
|
||||
.collect(Collectors.toList());
|
||||
Set<String> wmsArrivedSet = coilNos.isEmpty() ? new HashSet<>()
|
||||
: baseMapper.selectExistingSupplierCoilNos(coilNos).stream()
|
||||
.map(this::normCoil).collect(Collectors.toSet());
|
||||
Set<String> arrivedSet = coilNos.isEmpty() ? new HashSet<>()
|
||||
: baseMapper.selectExistingSupplierCoilNos(coilNos).stream().map(this::normCoil).collect(Collectors.toSet());
|
||||
Set<String> inTransitSet = coilNos.isEmpty() ? new HashSet<>()
|
||||
: baseMapper.selectInTransitSupplierCoilNos(coilNos).stream().map(this::normCoil).collect(Collectors.toSet());
|
||||
|
||||
int arrivedCount = 0;
|
||||
int transitCount = 0;
|
||||
BigDecimal arrivedWeight = BigDecimal.ZERO;
|
||||
BigDecimal transitWeight = BigDecimal.ZERO;
|
||||
for (ErpPurchasePlanDelivery d : deliveries) {
|
||||
int nowArrived = StringUtils.isNotBlank(d.getCoilNo()) && wmsArrivedSet.contains(normCoil(d.getCoilNo())) ? 1 : 0;
|
||||
// 状态有变化才回写,减少无谓更新
|
||||
if (d.getArrived() == null || d.getArrived() != nowArrived) {
|
||||
String coil = normCoil(d.getCoilNo());
|
||||
int nowArrived = !coil.isEmpty() && arrivedSet.contains(coil) ? 1 : 0;
|
||||
int nowTransit = nowArrived == 0 && !coil.isEmpty() && inTransitSet.contains(coil) ? 1 : 0;
|
||||
if (d.getArrived() == null || d.getArrived() != nowArrived
|
||||
|| d.getInTransit() == null || d.getInTransit() != nowTransit) {
|
||||
d.setArrived(nowArrived);
|
||||
d.setInTransit(nowTransit);
|
||||
deliveryMapper.updateById(d);
|
||||
}
|
||||
BigDecimal w = d.getCoilWeight() == null ? BigDecimal.ZERO : d.getCoilWeight();
|
||||
if (nowArrived == 1) {
|
||||
arrivedCount++;
|
||||
arrivedWeight = arrivedWeight.add(d.getCoilWeight() == null ? BigDecimal.ZERO : d.getCoilWeight());
|
||||
arrivedWeight = arrivedWeight.add(w);
|
||||
} else if (nowTransit == 1) {
|
||||
transitCount++;
|
||||
transitWeight = transitWeight.add(w);
|
||||
}
|
||||
}
|
||||
plan.setArrivedCount(arrivedCount);
|
||||
plan.setArrivedWeight(arrivedWeight);
|
||||
// 到货重量达到计划要求总重量 → 自动归档
|
||||
plan.setInTransitCount(transitCount);
|
||||
plan.setInTransitWeight(transitWeight);
|
||||
// 到货重量达到要求总重量 → 自动归档
|
||||
BigDecimal planWeight = plan.getPlanWeight() == null ? BigDecimal.ZERO : plan.getPlanWeight();
|
||||
boolean done = planWeight.compareTo(BigDecimal.ZERO) > 0 && arrivedWeight.compareTo(planWeight) >= 0;
|
||||
plan.setPlanStatus(done ? PLAN_STATUS_ARCHIVED : PLAN_STATUS_ONGOING);
|
||||
@@ -612,12 +572,9 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService {
|
||||
return map;
|
||||
}
|
||||
|
||||
/** 同时填充按重量、按卷数两个到货百分比 */
|
||||
/** 到货百分比按重量 = 已到货重量 / 要求总重量 */
|
||||
private void fillProgress(ErpPurchasePlanVo v) {
|
||||
v.setProgress(calcPct(v.getArrivedWeight(), v.getPlanWeight()));
|
||||
v.setProgressQty(calcPct(
|
||||
v.getArrivedCount() == null ? null : BigDecimal.valueOf(v.getArrivedCount()),
|
||||
v.getPlanQty() == null ? null : BigDecimal.valueOf(v.getPlanQty())));
|
||||
}
|
||||
|
||||
/** 百分比(0-100,保留2位) = num/den,封顶100 */
|
||||
@@ -630,13 +587,13 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService {
|
||||
return pct.min(BigDecimal.valueOf(100));
|
||||
}
|
||||
|
||||
/** 自动生成计划号:CG + yyyyMMdd + 4位流水 */
|
||||
/** 自动生成合同号:yyyyMMdd-当日序号(如 20260629-1) */
|
||||
private String generatePlanNo() {
|
||||
String prefix = "CG" + DateUtil.format(new Date(), "yyyyMMdd");
|
||||
String prefix = DateUtil.format(new Date(), "yyyyMMdd");
|
||||
Long todayCount = baseMapper.selectCount(Wrappers.lambdaQuery(ErpPurchasePlan.class)
|
||||
.likeRight(ErpPurchasePlan::getPlanNo, prefix));
|
||||
.likeRight(ErpPurchasePlan::getPlanNo, prefix + "-"));
|
||||
long seq = (todayCount == null ? 0L : todayCount) + 1L;
|
||||
return prefix + String.format("%04d", seq);
|
||||
return prefix + "-" + seq;
|
||||
}
|
||||
|
||||
private Date parseDate(String text) {
|
||||
|
||||
@@ -77,6 +77,31 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<!-- 在途卷号:钢卷表存在且 data_type=10 -->
|
||||
<select id="selectInTransitSupplierCoilNos" resultType="java.lang.String">
|
||||
SELECT DISTINCT supplier_coil_no
|
||||
FROM wms_material_coil
|
||||
WHERE del_flag = 0 AND data_type = 10
|
||||
AND supplier_coil_no IN
|
||||
<foreach collection="coilNos" item="c" open="(" separator="," close=")">
|
||||
#{c}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<!-- 厂商历史记忆(去重,可按关键字过滤) -->
|
||||
<select id="selectDistinctManufacturers" resultType="java.lang.String">
|
||||
SELECT manufacturer FROM (
|
||||
SELECT DISTINCT manufacturer
|
||||
FROM erp_purchase_plan_item
|
||||
WHERE del_flag = '0' AND manufacturer IS NOT NULL AND TRIM(manufacturer) <> ''
|
||||
<if test="kw != null and kw != ''">
|
||||
AND manufacturer LIKE CONCAT('%', #{kw}, '%')
|
||||
</if>
|
||||
) t
|
||||
ORDER BY manufacturer
|
||||
LIMIT 20
|
||||
</select>
|
||||
|
||||
<!-- 按合同关键字查关联的采购计划ID(订单编号/合同号/合同名称) -->
|
||||
<select id="selectPlanIdsByContractKeyword" resultType="java.lang.Long">
|
||||
SELECT DISTINCT r.plan_id
|
||||
|
||||
Reference in New Issue
Block a user