生产环节优化
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
-- 密炼生产计划维护(早/中/晚班)
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `mes_xsl_mixing_production_plan` (
|
||||
`id` varchar(32) NOT NULL COMMENT '主键',
|
||||
`sort_no` int DEFAULT NULL COMMENT '排序号',
|
||||
`machine_id` varchar(32) DEFAULT NULL COMMENT '机台ID(mes_xsl_equipment_ledger.id)',
|
||||
`machine_name` varchar(128) DEFAULT NULL COMMENT '机台名称冗余',
|
||||
|
||||
`morning_plan_id` varchar(32) DEFAULT NULL COMMENT '早班计划ID(母胶/终胶计划)',
|
||||
`morning_plan_type` varchar(2) DEFAULT NULL COMMENT '早班计划类型:M母胶/F终胶',
|
||||
`morning_order_no` varchar(64) DEFAULT NULL COMMENT '早班生产订单',
|
||||
`morning_order_date` date DEFAULT NULL COMMENT '早班订单日期',
|
||||
`morning_formula_name` varchar(128) DEFAULT NULL COMMENT '早班配方名称',
|
||||
`morning_plan_weight` decimal(18,6) DEFAULT NULL COMMENT '早班计划重量',
|
||||
`morning_planned_car_count` int DEFAULT NULL COMMENT '早班计划车数',
|
||||
`morning_scheduled_car_count` int DEFAULT NULL COMMENT '早班已排产车数',
|
||||
`morning_finished_car_count` int DEFAULT NULL COMMENT '早班完成车数',
|
||||
`morning_plan_count` int DEFAULT NULL COMMENT '早班计划',
|
||||
`morning_remark` varchar(500) DEFAULT NULL COMMENT '早班备注',
|
||||
|
||||
`noon_plan_id` varchar(32) DEFAULT NULL COMMENT '中班计划ID(母胶/终胶计划)',
|
||||
`noon_plan_type` varchar(2) DEFAULT NULL COMMENT '中班计划类型:M母胶/F终胶',
|
||||
`noon_order_no` varchar(64) DEFAULT NULL COMMENT '中班生产订单',
|
||||
`noon_order_date` date DEFAULT NULL COMMENT '中班订单日期',
|
||||
`noon_formula_name` varchar(128) DEFAULT NULL COMMENT '中班配方名称',
|
||||
`noon_plan_weight` decimal(18,6) DEFAULT NULL COMMENT '中班计划重量',
|
||||
`noon_planned_car_count` int DEFAULT NULL COMMENT '中班计划车数',
|
||||
`noon_scheduled_car_count` int DEFAULT NULL COMMENT '中班已排产车数',
|
||||
`noon_finished_car_count` int DEFAULT NULL COMMENT '中班完成车数',
|
||||
`noon_plan_count` int DEFAULT NULL COMMENT '中班计划',
|
||||
`noon_remark` varchar(500) DEFAULT NULL COMMENT '中班备注',
|
||||
|
||||
`night_plan_id` varchar(32) DEFAULT NULL COMMENT '晚班计划ID(母胶/终胶计划)',
|
||||
`night_plan_type` varchar(2) DEFAULT NULL COMMENT '晚班计划类型:M母胶/F终胶',
|
||||
`night_order_no` varchar(64) DEFAULT NULL COMMENT '晚班生产订单',
|
||||
`night_order_date` date DEFAULT NULL COMMENT '晚班订单日期',
|
||||
`night_formula_name` varchar(128) DEFAULT NULL COMMENT '晚班配方名称',
|
||||
`night_plan_weight` decimal(18,6) DEFAULT NULL COMMENT '晚班计划重量',
|
||||
`night_planned_car_count` int DEFAULT NULL COMMENT '晚班计划车数',
|
||||
`night_scheduled_car_count` int DEFAULT NULL COMMENT '晚班已排产车数',
|
||||
`night_finished_car_count` int DEFAULT NULL COMMENT '晚班完成车数',
|
||||
`night_plan_count` int DEFAULT NULL COMMENT '晚班计划',
|
||||
`night_remark` varchar(500) DEFAULT NULL COMMENT '晚班备注',
|
||||
|
||||
`tenant_id` int DEFAULT NULL COMMENT '租户',
|
||||
`sys_org_code` varchar(64) DEFAULT NULL COMMENT '部门编码',
|
||||
`create_by` varchar(32) DEFAULT NULL COMMENT '创建人',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_by` varchar(32) DEFAULT NULL COMMENT '更新人',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`del_flag` int DEFAULT '0' COMMENT '删除标记(0正常1删除)',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_mxmp_machine` (`machine_id`),
|
||||
KEY `idx_mxmp_sort` (`sort_no`),
|
||||
KEY `idx_mxmp_tenant` (`tenant_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='MES密炼生产计划维护';
|
||||
@@ -0,0 +1,23 @@
|
||||
-- 原材料需求计划明细表
|
||||
CREATE TABLE IF NOT EXISTS `mes_xsl_raw_material_demand_plan` (
|
||||
`id` varchar(32) NOT NULL COMMENT '主键',
|
||||
`machine_id` varchar(32) DEFAULT NULL COMMENT '机台ID',
|
||||
`machine_name` varchar(64) DEFAULT NULL COMMENT '机台名称',
|
||||
`erp_code` varchar(64) NOT NULL COMMENT 'ERP编号',
|
||||
`raw_material_name` varchar(128) NOT NULL COMMENT '原材料名称',
|
||||
`demand_weight` decimal(18,6) DEFAULT '0.000000' COMMENT '需求重量',
|
||||
`standard_weight` decimal(18,6) DEFAULT '0.000000' COMMENT '标准重量',
|
||||
`actual_weight` decimal(18,6) DEFAULT '0.000000' COMMENT '实际重量',
|
||||
`tenant_id` int DEFAULT NULL COMMENT '租户ID',
|
||||
`sys_org_code` varchar(64) DEFAULT NULL COMMENT '所属部门',
|
||||
`create_by` varchar(50) DEFAULT NULL COMMENT '创建人',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_by` varchar(50) DEFAULT NULL COMMENT '更新人',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`del_flag` tinyint(1) DEFAULT '0' COMMENT '删除标识(0-正常,1-删除)',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_raw_material_demand_machine` (`machine_name`),
|
||||
KEY `idx_raw_material_demand_erp` (`erp_code`),
|
||||
KEY `idx_raw_material_demand_name` (`raw_material_name`),
|
||||
KEY `idx_raw_material_demand_del` (`del_flag`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='原材料需求计划明细';
|
||||
@@ -0,0 +1,141 @@
|
||||
package org.jeecg.modules.xslmes.test;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import org.jeecg.JeecgSystemApplication;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.modules.mes.material.entity.MesMaterial;
|
||||
import org.jeecg.modules.mes.material.mapper.MesMaterialMapper;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslFinalBatchPlan;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslMasterBatchPlan;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslMixingSpec;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslProductionOrder;
|
||||
import org.jeecg.modules.xslmes.mapper.MesXslFinalBatchPlanMapper;
|
||||
import org.jeecg.modules.xslmes.mapper.MesXslMasterBatchPlanMapper;
|
||||
import org.jeecg.modules.xslmes.mapper.MesXslMixingSpecMapper;
|
||||
import org.jeecg.modules.xslmes.mapper.MesXslProductionOrderMapper;
|
||||
import org.jeecg.modules.xslmes.service.IMesXslProductionOrderService;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@SpringBootTest(
|
||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
classes = JeecgSystemApplication.class)
|
||||
@Transactional
|
||||
class MesXslProductionOrderSplitIntegrationTest {
|
||||
|
||||
@Resource private IMesXslProductionOrderService productionOrderService;
|
||||
@Resource private MesXslProductionOrderMapper productionOrderMapper;
|
||||
@Resource private MesXslMasterBatchPlanMapper masterBatchPlanMapper;
|
||||
@Resource private MesXslFinalBatchPlanMapper finalBatchPlanMapper;
|
||||
@Resource private MesMaterialMapper materialMapper;
|
||||
@Resource private MesXslMixingSpecMapper mixingSpecMapper;
|
||||
|
||||
@Test
|
||||
void splitShouldGenerateB1B2AndFWhenSegmentCountIs3() {
|
||||
String base = "UT" + System.currentTimeMillis();
|
||||
MesXslProductionOrder order = createOrder(base, 3);
|
||||
|
||||
createMaterial("B1" + base + "SA01", "B1-" + base);
|
||||
createMaterial("B2" + base + "SA01", "B2-" + base);
|
||||
createMaterial("F" + base + "SA01", "F-" + base);
|
||||
|
||||
createMixingSpec("B1" + base + "SA01");
|
||||
createMixingSpec("B2" + base + "SA01");
|
||||
createMixingSpec("F" + base + "SA01");
|
||||
|
||||
List<MesXslMasterBatchPlan> masters = productionOrderService.splitToMasterBatchPlan(order.getId());
|
||||
Assertions.assertEquals(2, masters.size(), "段数=3时应生成2条母胶计划");
|
||||
|
||||
List<MesXslMasterBatchPlan> dbMasters =
|
||||
masterBatchPlanMapper.selectList(
|
||||
new LambdaQueryWrapper<MesXslMasterBatchPlan>()
|
||||
.eq(MesXslMasterBatchPlan::getSourceOrderId, order.getId())
|
||||
.orderByAsc(MesXslMasterBatchPlan::getMaterialCode));
|
||||
Assertions.assertEquals(2, dbMasters.size());
|
||||
Assertions.assertEquals("B1" + base, dbMasters.get(0).getMaterialCode());
|
||||
Assertions.assertEquals("B2" + base, dbMasters.get(1).getMaterialCode());
|
||||
|
||||
MesXslFinalBatchPlan finalPlan =
|
||||
finalBatchPlanMapper.selectOne(
|
||||
new LambdaQueryWrapper<MesXslFinalBatchPlan>()
|
||||
.eq(MesXslFinalBatchPlan::getSourceOrderId, order.getId())
|
||||
.last("LIMIT 1"));
|
||||
Assertions.assertNotNull(finalPlan, "应生成1条终胶计划");
|
||||
Assertions.assertEquals("F" + base, finalPlan.getMaterialCode());
|
||||
|
||||
MesXslProductionOrder updated = productionOrderMapper.selectById(order.getId());
|
||||
Assertions.assertEquals(1, updated.getSplitStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
void splitShouldFailWhenAnyMixingSpecMissing() {
|
||||
String base = "UT" + (System.currentTimeMillis() + 7);
|
||||
MesXslProductionOrder order = createOrder(base, 3);
|
||||
|
||||
createMaterial("B1" + base + "SA01", "B1-" + base);
|
||||
createMaterial("B2" + base + "SA01", "B2-" + base);
|
||||
createMaterial("F" + base + "SA01", "F-" + base);
|
||||
|
||||
// 故意缺少 FxxxSA01
|
||||
createMixingSpec("B1" + base + "SA01");
|
||||
createMixingSpec("B2" + base + "SA01");
|
||||
|
||||
JeecgBootException ex =
|
||||
Assertions.assertThrows(
|
||||
JeecgBootException.class,
|
||||
() -> productionOrderService.splitToMasterBatchPlan(order.getId()));
|
||||
Assertions.assertEquals("对应物料的混炼示方不存在,请先生成混炼示方!", ex.getMessage());
|
||||
|
||||
List<MesXslMasterBatchPlan> dbMasters =
|
||||
masterBatchPlanMapper.selectList(
|
||||
new LambdaQueryWrapper<MesXslMasterBatchPlan>()
|
||||
.eq(MesXslMasterBatchPlan::getSourceOrderId, order.getId()));
|
||||
Assertions.assertTrue(dbMasters.isEmpty(), "失败后母胶计划应回滚");
|
||||
|
||||
MesXslFinalBatchPlan finalPlan =
|
||||
finalBatchPlanMapper.selectOne(
|
||||
new LambdaQueryWrapper<MesXslFinalBatchPlan>()
|
||||
.eq(MesXslFinalBatchPlan::getSourceOrderId, order.getId())
|
||||
.last("LIMIT 1"));
|
||||
Assertions.assertNull(finalPlan, "失败后终胶计划应回滚");
|
||||
|
||||
MesXslProductionOrder unchanged = productionOrderMapper.selectById(order.getId());
|
||||
Assertions.assertTrue(
|
||||
unchanged.getSplitStatus() == null || unchanged.getSplitStatus() == 0, "失败后拆分状态不应置为已拆分");
|
||||
}
|
||||
|
||||
private MesXslProductionOrder createOrder(String baseCode, int segmentCount) {
|
||||
MesXslProductionOrder order = new MesXslProductionOrder();
|
||||
order.setProductionOrderNo("PO-" + baseCode);
|
||||
order.setOrderDate(new Date());
|
||||
order.setProcessSegmentCount(segmentCount);
|
||||
order.setMesMaterialName(baseCode);
|
||||
order.setMaterialCode(baseCode);
|
||||
order.setPlanQty(new BigDecimal("100.00"));
|
||||
order.setSplitStatus(0);
|
||||
order.setDelFlag(0);
|
||||
productionOrderMapper.insert(order);
|
||||
return order;
|
||||
}
|
||||
|
||||
private void createMaterial(String code, String name) {
|
||||
MesMaterial material = new MesMaterial();
|
||||
material.setMaterialCode(code);
|
||||
material.setMaterialName(name);
|
||||
material.setDelFlag(0);
|
||||
materialMapper.insert(material);
|
||||
}
|
||||
|
||||
private void createMixingSpec(String specName) {
|
||||
MesXslMixingSpec spec = new MesXslMixingSpec();
|
||||
spec.setSpecName(specName);
|
||||
spec.setDelFlag(0);
|
||||
mixingSpecMapper.insert(spec);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user