跳至主要內容

计划单

chanchaw大约 23 分钟weberp开发手册

概述

染色计划单JSP页面:WEB-INF/web/MainPages/pages_SCJH/SC_DyePlanBill.jsp
染色计划单:web\MainPages\pages_SCJH\SC_PlanBill_Dye.js
印花计划单:web\MainPages\pages_SCJH\SC_PlanBill_Flat.js
染色+印花计划单:web\MainPages\pages_SCJH\SC_PlanBill_Flat_Dye.js
控制器:account.controller.forms.PlanBillController
封号API 对应的方法是:updateLocked
服务接口:account.service.PlanBillService
服务实现类:account.service.impl.PlanBillServiceImpl
对应的车数分配数量是表 detailbill_plan

复制

单张复制和多张复制使用同一个API planBill/saveCopiedBill.do

回修缸单

回修缸单的缸号是在原缸号的最后新增一位数字为1,表示原缸号第一次回修,如果原缸号还有第二次回修则在原缸号的后面新增数字2,表示原缸号生成的第二次回修缸单

关联 - 计划领料数据

根据下面方法找到计划单关联的白坯计划领料主表数据

select * from bpbillmain WHERE vatNO='Y22094208' LIMIT 100;
# 主表和明细表通过单据编号关联,所以查找对应的明细数据是
select * from bpbilldetail WHERE billCode='BP2209290082';

关联 - 车数数据

数据表:detailbill_plan

-- auto-generated definition
create table detailbill_plan
(
  id bigint(11) auto_increment comment '主键'
  primary key,
  fId int null comment '=bpbilldetail.id = 计划领料单明细主键',
  vatNO varchar(80) null comment '对应缸单的缸号',
  serialNO int null comment '车号',
  piece double null comment '匹数',
  kilo double null comment '公斤',
  meter double null comment '米数',
  constraint detailbill_plan_ibfk_1
  foreign key (fId) references bpbilldetail (id),
  constraint detailbill_plan_ibfk_2
  foreign key (vatNO) references plan (vatNum)
)
comment '白坯明细单据对应的细码单';

create index fk_detailbill_p_fk_01
on detailbill_plan (fId);

create index fk_detailbill_p_fk_02
on detailbill_plan (vatNO);

查询获取计划单对应的领料的车数数据

select * from detailbill_plan where vatNO='Y22121383';

关联 - 工序工艺

select * from craftdetail_plan LIMIT 100;

批量生成

2022年4月28日 09:32:04 在白玉兰分支的计划单页面 SC_DyePlanBill.jsp 的基础上制作批量生成计划单的页面 - SC_DyePlanBill_Batch.jsp

后来又制作了根据手动设置的匹数、公斤、米数生成领料(之前是通过平均匹重生成领料数量) JSP - SC_FlatPlanBill_new.jsp 保存的后台请求是 - account.controller.forms.PlanBillController # saveBatch

最初为白玉兰项目制作本逻辑,后来发现多批次混合领料时由于平均匹重的问题导致缸单上显示的计划匹数、公斤与操作员设置的不同,后来修改逻辑严格按照操作员设置的匹数、公斤生成,会导致第二批次的白坯剩余匹数、公斤重新计算匹重时和入库数量计算的匹重不同,该逻辑要使用白玉兰的逻辑,覆盖文件 MultipleReplicationServiceImpl 的代码,会有依赖项要求更新,一起更新即可。

批量生成计划单时的混合领料
批量生成计划单时的混合领料

提示

参数

批量生成计划单页面选择一个批次号的白坯,足够用,每缸2匹,总共3缸,发送给后端的参数如下图
批量生成计划单白坯分配方案
参数数据如下:

PlanBillBatch{
	planBill=PlanBill{
		cpAlias='null', processnamenow='null', processnamenext='null', mainid=null, id=null, date=Thu Apr 18 00:00:00 CST 2024, 
		submitDate=Sun Apr 14 00:00:00 CST 2024, orderNo='240325004', fid=2049, pId=null, clientId='JDL', tintingTypeId='1', 
		client='null', craftMan='null', alias='佳得利', remark='null', priceType='', craftId=25, vatNum='Y24007186', colorClothId='', 
		bFinished=null, vatBillRemark='', colorClothName='双面北极绒', yd_specification='', sendRemark='', whiteSpecification='', 
		fd_specification='', hg_specification='', cp_specification='边1.9*210-215', colorNoId='D243007B', color='黑色', patternId='', 
		packageRequire='', qualityRequire='', piece=2.0, kilogram=0.0, fixedKG=null, wayIntoVatSid='', salesMan='', planKilo=null, 
		planMeter=0.0, guessDestory=null, oneToMore='整卷', mid=null, createDate=null, netWeight=null, meter=null, center=null, machineNO=1, 
		netWeightAtube=null, paperTube=0.6, packageWeight=null, empty=null, emptyHidden=0.0, fixedMeter=null, packageType='单袋', roll='', 
		tabStyle='', supplier='null', codeBillType='221002', printNum=1, abnormal='', status=null, count=null, bLabelCopies=null, 
		bColorEng='null', printCount=null, calculateState=0, isRelease=null, bQtyFact=null, bPiShuFact=null, bMeterFact=null, 
		releaseDate=null, isOrdered=null, compFashion=0, repaireStation=null, clientCraft='', tubeNumber=null, clientColorno='', 
		clientColor='', merge=null, serialNo=null, increasePrice=0.00, orderCode='', bStarted=null, machinetypeId=null, 
		planType=null, orderdtlIds=[2049], pickway=null, 

		detailBill=[DetailbillPlan{id=null, fId=22170, vatNO='null', serialNO=1, piece=2.0, kilo=0.0, meter=null}], 

		greyFabricDetail=[
			BpBillInfo{id=22170, pId=22170, vId=null, 
		billCode='BPR2404080001', date=null, billtypeId=null, billtypeName='null', clientId='JDL', company='佳得利', 
		greyfabricId=12, greyfabric='法兰绒', title='490*4*188', ordercode='null', kiloheight='null', pairs=124.0, kilo=5330.8, meter=null, 
		valuateId=null, valuateName='null', price=null, total=null, number=null, cage='', product_name='null', cutterId='SX', cutter='绍兴', 
		targetUnitId='null', targetUnit='null', operatorId='null', operator='null', pairNO='P240408001', tip='null', status=null, isOut=null, 
		isVerification=null, deliveryNo='null', maxPieceWeight=null, minPieceWeight=null, avgPieceWeight=null, widthgramme='null', provider01='', 
		provider02='null', spares01='null', spares02='null', sparei01=null, sparei02=null, spared01=null, spared02=null, sparet01=null, sparet02=null, 
		bpBill=[], detailBill=[], bpbilldetailMsgs=[]}], exportCounter=null,

		procedure=[
			CraftdetailPlan{sId=null, vatNum='null', fId=25, processId='1', process='白坯翻布', remark='null', mark=null, serialNO=1, createDate=null, finishedsign=null}, 
			CraftdetailPlan{sId=null, vatNum='null', fId=25, processId='2', process='白坯缝头', remark='null', mark=null, serialNO=2, createDate=null, finishedsign=null}, 
			CraftdetailPlan{sId=null, vatNum='null', fId=25, processId='7', process='白坯梳毛', remark='null', mark=null, serialNO=3, createDate=null, finishedsign=null}, 
			CraftdetailPlan{sId=null, vatNum='null', fId=25, processId='8', process='白坯烫光', remark='null', mark=null, serialNO=4, createDate=null, finishedsign=null}, 
			CraftdetailPlan{sId=null, vatNum='null', fId=25, processId='3', process='白坯预定', remark='null', mark=null, serialNO=5, createDate=null, finishedsign=null}, 
			CraftdetailPlan{sId=null, vatNum='null', fId=25, processId='16', process='定-翻身', remark='null', mark=null, serialNO=6, createDate=null, finishedsign=null}, 
			CraftdetailPlan{sId=null, vatNum='null', fId=25, processId='15', process='预定拉车', remark='null', mark=null, serialNO=7, createDate=null, finishedsign=null}, 
			CraftdetailPlan{sId=null, vatNum='null', fId=25, processId='4', process='染色', remark='null', mark=null, serialNO=8, createDate=null, finishedsign=null}, 
			CraftdetailPlan{sId=null, vatNum='null', fId=25, processId='13', process='染色上柔', remark='null', mark=null, serialNO=9, createDate=null, finishedsign=null}, 
			CraftdetailPlan{sId=null, vatNum='null', fId=25, processId='5', process='染色脱水', remark='null', mark=null, serialNO=10, createDate=null, finishedsign=null}, 
			CraftdetailPlan{sId=null, vatNum='null', fId=25, processId='30', process='染色理布', remark='null', mark=null, serialNO=11, createDate=null, finishedsign=null}, 
			CraftdetailPlan{sId=null, vatNum='null', fId=25, processId='14', process='定烘干', remark='null', mark=null, serialNO=12, createDate=null, finishedsign=null}, 
			CraftdetailPlan{sId=null, vatNum='null', fId=25, processId='20', process='烘干落车', remark='null', mark=null, serialNO=13, createDate=null, finishedsign=null}, 
			CraftdetailPlan{sId=null, vatNum='null', fId=25, processId='21', process='陈塘装卸', remark='null', mark=null, serialNO=14, createDate=null, finishedsign=null}, 
			CraftdetailPlan{sId=null, vatNum='null', fId=25, processId='22', process='新厂倒布', remark='null', mark=null, serialNO=15, createDate=null, finishedsign=null}, 
			CraftdetailPlan{sId=null, vatNum='null', fId=25, processId='23', process='新厂拉毛', remark='null', mark=null, serialNO=16, createDate=null, finishedsign=null}, 
			CraftdetailPlan{sId=null, vatNum='null', fId=25, processId='24', process='新厂反梳毛', remark='null', mark=null, serialNO=17, createDate=null, finishedsign=null}, 
			CraftdetailPlan{sId=null, vatNum='null', fId=25, processId='25', process='新厂反剪毛', remark='null', mark=null, serialNO=18, createDate=null, finishedsign=null}, 
			CraftdetailPlan{sId=null, vatNum='null', fId=25, processId='26', process='新厂正烫光', remark='null', mark=null, serialNO=19, createDate=null, finishedsign=null}, 
			CraftdetailPlan{sId=null, vatNum='null', fId=25, processId='27', process='新厂反烫光', remark='null', mark=null, serialNO=20, createDate=null, finishedsign=null}, 
			CraftdetailPlan{sId=null, vatNum='null', fId=25, processId='28', process='新厂大摇粒', remark='null', mark=null, serialNO=21, createDate=null, finishedsign=null}, 
			CraftdetailPlan{sId=null, vatNum='null', fId=25, processId='19', process='定新厂成品', remark='null', mark=null, serialNO=22, createDate=null, finishedsign=null}, 
			CraftdetailPlan{sId=null, vatNum='null', fId=25, processId='29', process='新厂单袋', remark='null', mark=null, serialNO=23, createDate=null, finishedsign=null}
		]
	}, 

	planMain=PlanMain [Hash = 1078559900, iid=null, parent_id=2049, batch_count=1, ps=6, kilo=0, meter=0, cart_count=3, create_time=null, serialVersionUID=1], 

	distributeList=[
		MultipleReplicationModel{piece=2.0, kilo=0.0, meter=null}, 
		MultipleReplicationModel{piece=2.0, kilo=0.0, meter=null}, 
		MultipleReplicationModel{piece=2.0, kilo=0.0, meter=null}
	]
}

提示

优化批量生成的速度

  1. 向白坯表新增的速度优化 批量生成计划单时间过长,白玉兰每次都要生成10张以上的数量 - 10张大概27秒左右。导致白坯核销领料速度也慢了。本日开始优化该功能,通过打日志找到在方法 account.service.baseservice.SourcePlanBillServiceImplI # save 的代码行:
if (billDao.insertDetailForPlan(info) > 0) {

处要耗时 1.4s 左右,单纯的 insert 语句执行这个时长,速度太慢了。通过 mybati 打印日志其 sql 语句和参数如下:(关联的 mapper方法是:BpBillDetailMapper.xml # insertDetailForPlan)

# 下面是 sql 语句
INSERT INTO bpbilldetail (pId, billCode, billtypeId, clientId, greyfabricId, title, kiloheight, pairs, kilo, meter, valuateId, price, total, number, cage, product_name, cutterId, targetUnitId, 
pairNO, tip, isOut, isVerification, ordercode) 
SELECT ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 
if(isnull(?) || length(trim(?)) < 1, NULL, ?), ?, ?, IFNULL(?, 1), IFNULL(?, 0), ? 
FROM DUAL WHERE exists(SELECT b.id FROM bpbillmain a 
LEFT JOIN bpbilldetail b ON a.billCode = b.billCode AND b.status = 1 
LEFT JOIN billtype c ON b.billtypeId = c.id 
# 计划扣库 
LEFT JOIN (
	SELECT a.pId, sum(if(b.vatNum IS NOT NULL, b.kilo, a.kilo)) + ifnull(c.kilo, 0) kilo, 
	sum(if(b.vatNum IS NOT NULL, b.pairs, a.pairs)) + ifnull(c.pairs, 0) pairs, 
	sum(if(b.vatNum IS NOT NULL, b.meter, a.meter)) + ifnull(c.meter, 0) meter 
	FROM (
		SELECT sum(b.kilo) kilo, sum(b.pairs) pairs, 
		sum(b.meter) meter, a.vatNO, b.pId 
		FROM bpbillmain a 
		LEFT JOIN bpbilldetail b ON a.billCode = b.billCode AND b.status = 1 
		LEFT JOIN billtype c ON b.billtypeId = c.id 
		WHERE a.status = 1 AND a.vatNO IS NOT NULL AND b.isOut = 0 
		GROUP BY b.pId, a.vatNO
	) a 
	# 领料扣库 
	LEFT JOIN (
		SELECT sum(b.kilo) kilo, sum(b.pairs) pairs, sum(b.meter) meter, b.vId, c.vatNum, b.pId 
		FROM bpbillmain a 
		LEFT JOIN bpbilldetail b ON a.billCode = b.billCode AND b.status = 1 
		LEFT JOIN plan c ON b.vId = c.id 
		WHERE a.status = 1 AND b.isOut IN (1, 2) AND b.vId IS NOT NULL 
		GROUP BY b.pId, b.vId) b ON b.pId = a.pId AND b.vatNum = a.vatNO 
		# 退货盘点 
		LEFT JOIN (
			SELECT b.pId, ifnull(sum(b.pairs), 0) pairs, ifnull(sum(b.kilo), 0) kilo, ifnull(sum(b.meter), 0) meter 
			FROM bpbillmain a 
			LEFT JOIN bpbilldetail b ON a.billCode = b.billCode AND b.status = 1 
			LEFT JOIN billtype c ON b.billtypeId = c.id 
			WHERE a.status = 1 AND b.isOut IN (1, 2) AND isnull(b.vId) 
			GROUP BY b.pId
		) c ON c.pId = a.pId 
		GROUP BY a.pId
	) d ON d.pId = b.id 
	WHERE c.accessMode IN (1, 0) AND b.isOut IN (1, 2) AND a.status = 1 AND b.id = ? 
	AND (ROUND(ifnull(b.kilo, 0) - ifnull(d.kilo, 0) - ifnull(?, 0), 1) >= 0 
	AND ROUND(ifnull(b.meter, 0) - ifnull(d.meter, 0) - ifnull(?, 0), 1) >= 0 
	AND ROUND(ifnull(b.pairs, 0) - ifnull(d.pairs, 0) - ifnull(?, 0), 1) >= 0)) 
	OR IFNULL((SELECT B_Value FROM g_config_oneint WHERE B_GroupName = 'WEB应用_计划是否允许负库存' LIMIT 1), 0) = 1
	
# 下面是参数,按照上面 ? 的顺序逐一填入即可
128791(Long), BP2206130001(String), 3(Integer), YWF(String), 24(Integer), null, null, 3.0(Double), 60.0(Double), 0.0(Double), null, null, null, null,(String), null, JQ(String), null, null, null, P220606037(String), null, 0(Integer), null, null, 128791(Long), 60.0(Double), 0.0(Double), 3.0(Double)

拼接实际参数后完整的 sql 是:

INSERT INTO bpbilldetail (pId, billCode, billtypeId, clientId, greyfabricId, title, kiloheight, pairs, kilo, meter, valuateId, price, total, number, cage, product_name, cutterId, targetUnitId,
pairNO, tip, isOut, isVerification, ordercode)
SELECT ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,# 17个
if(isnull(?) || length(trim(?)) < 1, NULL, ?), ?, ?, IFNULL(?, 1), IFNULL(?, 0), ? # 8个
FROM DUAL WHERE exists(SELECT b.id FROM bpbillmain a 
LEFT JOIN bpbilldetail b ON a.billCode = b.billCode AND b.status = 1 
LEFT JOIN billtype c ON b.billtypeId = c.id 
# 计划扣库 
LEFT JOIN (
	SELECT a.pId, sum(if(b.vatNum IS NOT NULL, b.kilo, a.kilo)) + ifnull(c.kilo, 0) kilo, 
	sum(if(b.vatNum IS NOT NULL, b.pairs, a.pairs)) + ifnull(c.pairs, 0) pairs, 
	sum(if(b.vatNum IS NOT NULL, b.meter, a.meter)) + ifnull(c.meter, 0) meter 
	FROM (
		SELECT sum(b.kilo) kilo, sum(b.pairs) pairs, 
		sum(b.meter) meter, a.vatNO, b.pId 
		FROM bpbillmain a 
		LEFT JOIN bpbilldetail b ON a.billCode = b.billCode AND b.status = 1 
		LEFT JOIN billtype c ON b.billtypeId = c.id 
		WHERE a.status = 1 AND a.vatNO IS NOT NULL AND b.isOut = 0 
		GROUP BY b.pId, a.vatNO
	) a 
	# 领料扣库 
	LEFT JOIN (
		SELECT sum(b.kilo) kilo, sum(b.pairs) pairs, sum(b.meter) meter, b.vId, c.vatNum, b.pId 
		FROM bpbillmain a 
		LEFT JOIN bpbilldetail b ON a.billCode = b.billCode AND b.status = 1 
		LEFT JOIN plan c ON b.vId = c.id 
		WHERE a.status = 1 AND b.isOut IN (1, 2) AND b.vId IS NOT NULL 
		GROUP BY b.pId, b.vId
	) b ON b.pId = a.pId AND b.vatNum = a.vatNO
	# 退货盘点
	LEFT JOIN (
        SELECT b.pId, ifnull(sum(b.pairs), 0) pairs, ifnull(sum(b.kilo), 0) kilo, ifnull(sum(b.meter), 0) meter
        FROM bpbillmain a
        LEFT JOIN bpbilldetail b ON a.billCode = b.billCode AND b.status = 1
        LEFT JOIN billtype c ON b.billtypeId = c.id
        WHERE a.status = 1 AND b.isOut IN (1, 2) AND isnull(b.vId)
        GROUP BY b.pId
	) c ON c.pId = a.pId
	GROUP BY a.pId
) d ON d.pId = b.id
WHERE c.accessMode IN (1, 0) AND b.isOut IN (1, 2) AND a.status = 1 AND b.id = ?
AND (ROUND(ifnull(b.kilo, 0) - ifnull(d.kilo, 0) - ifnull(?, 0), 1) >= 0
AND ROUND(ifnull(b.meter, 0) - ifnull(d.meter, 0) - ifnull(?, 0), 1) >= 0
AND ROUND(ifnull(b.pairs, 0) - ifnull(d.pairs, 0) - ifnull(?, 0), 1) >= 0))
OR IFNULL((SELECT B_Value FROM g_config_oneint WHERE B_GroupName = 'WEB应用_计划是否允许负库存' LIMIT 1), 0) = 1;

最后一行 or 是要求满足下面两个条件其中之一才可以写入数据:

  1. 当前可用库存足够本计划单的计划数量
  2. 系统配置中设置了“允许计划负库存” 白玉兰这种客户则可直接省略 where exists 之后的所有代码,可以将时长从 1.4s 降低到14ms。以此加快批量生成缸单的速度。
  3. 构建每个缸单车数数据的优化 初次制作批量生成时每生成一个缸单都要查询多个批次号的白坯库存数据,一次查询库存耗时800ms+。每生成一张就查询一次太耗费时间,本次调整为在循环生成之前查询一次库存,然后在每次生成缸单时将库存数据传入。本方法要同时修改接口 account.service.PlanMeterialHandler 下的方法 Map<Long, List<DetailbillPlan>> createLathesNew(List<GreyFabricReposity> greyFabricReposityList, int count, List<DetailbillPlan> list) throws Exception; 的3个实现方法,将第一个参数 ids 修改为传入白坯库存数组数据

平均匹重相关
入库白坯情况如下:

批次号入库匹数入库公斤平均匹重
P12060030
P250175035

批量生成计划单安排如下: 匹数:15,公斤:450,车数:2,缸单:2 系统自动分配结果如下:

缸号 车号 匹数 公斤 批次号 01 01 15 450 P1 02 02 5 150 P1 02 02 10 300 P2

看上面表格第一缸的一车只有批次号P1的15匹,450公斤够用了 但是第二缸要拼凑P1的剩余5匹150公斤 + P2的10匹300公斤,才能符合计划的15匹450公斤的要求 所以系统在使用两个批次的白坯拼凑第二缸单时并没有考虑平均匹重,单纯的是用清批次P1,然后剩余的数量使用P2补充,所以此次批量生成计划单后会看到P1用清,P2剩余40匹1450公斤,貌似P2的平均匹重不对了。 建议不要使用平均匹重重新计算第二缸单的公斤或者匹数,应该严格参照操作员输入的匹数、公斤生成计划单上的计划数量。

右侧缸单列表

右边表格ID = list,请求数据的后台API - planBill/today_vat_list

生成缸号

先介绍从订单序时表生成缸单的逻辑 - 保存缸单时使用了另外一套重新生成缸号 缸单 JS 中请求 account.controller.basicdata.GenerateCodeController 中的方法 getPlanBillGCode 生成最新的缸号,通过服务 account.service.impl.GenerateCodeServiceImpl 的方法 getVatNum 生成新缸号 对应的 mybatis 的 xml 文件是 account/entity/Mapping/GenerateCodeMapper.xml 使用的存储过程是generate_plan_vatNo

2022年3月13日 08:29:42 白玉兰今年一开始使用时采用的逻辑是一缸一张,后来由于职工拉车不方便,邵总决定调整为一车一张,进入测试完毕等待更新。开始实现本逻辑时做了同银海印花一样的,染色、印花的自增编号共用一套,后来修改为染色、印花各自使用一套自增编号。主要对存储过程 generate_plan_vatNo_fuse 进行了修改。之后有同白玉兰一样的逻辑的客户将白玉兰的该存储过程拷贝来即可。有同银海印花一样的逻辑,从银海印花的服务器拷贝该存储过程。

保存

保存的请求来自控制器 account.controller.forms.PlanBillController 的方法 getFlatPlanBill 对应的调用了服务实现类 account.service.PlanBillService 的方法 savePlanBill,对应的 服务实现类是 account.service.impl.PlanBillServiceImpl 以及其方法 savePlanBill ,对应的 mapper 是 account/entity/Mapping/PlanBillMapper.xml 的方法 。 保存计划单的时候会重新生成一个缸号用来覆盖初次打开时候生成的缸号(防止多端操作导致缸号冲突)用到了服务实现类 account.service.impl.GenerateCodeServiceImpl 的方法 getPlanBillVatNum,这里的再次生成缸号在持久层使用的是同一个函数,不过在当前的保存计划单的服务实现类中将得到的缸号重新按照 染色=1,印花=2,混合=3 修改缸号,将 R20100001 修改为了 R10100001,R表示染色,后面的1表示染色,0表示2020年的最后一个0,10表示10月,最后的0001是自增数字

生成新缸号

mapper 文件 account/entity/Mapping/GenerateCodeMapper.xml 中的方法 getPlanBillVatNum 用于生成新的缸号,对应的数据库中的函数是 generate_plan_vatNo,这里生成的缸号字母后面的第一个数字是不对的,还要通过服务 account.service.impl.PlanBillServiceImpl 中的一个方法 savePlanBill 中根据染色、印花、混合修改后返回给前端的才是正确的

缸号规则

白玉兰缸号规则 一车一张缸单,缸号自增位数为6位,取消中间的月份的两位数字,最终缸号规则是: 前缀RY(R表示染色,Y表示印花)+1或者2(1表示染色,2表示印花)+年份(1位数字)+6位长度的自增数字 软件中需要调整的地方:

  • config_billcode 的 “单据编号_计数位数” = 4
  • config_billcode 的 “单据编号_计数清零” = M
  • 替换 GenerateCodeMapper.xml 中的方法 getPlanBillVatNum 调用的存储过程为 generate_plan_vatNo_fuse 该存储过程代码如下:
CREATE
DEFINER = root@`%` FUNCTION generate_plan_vatNo_fuse(prefix VARCHAR(50)) RETURNS VARCHAR(100)
BEGIN
# 2022年5月29日 12:10:26 来自白玉兰
# 缸号中间的月份划归为自增数字使用,保留前面的一位长度的年份
# 一车一张要求自增数量位数较多
#计划开单缸号生成的存储过程
#传入参数为单据的前缀
DECLARE currentDate VARCHAR(50);  #日期号
DECLARE newOrderNo VARCHAR(80);   #最新的单据编号
DECLARE oldOrderNo VARCHAR(80);   #离本次最新的单据编号
DECLARE maxNo BIGINT DEFAULT 0;        #当前周期内最大的计数
DECLARE num INT(11);                            #时间字段位数
DECLARE year_num INT(11);                    #年份位数
DECLARE amount_num INT(11);                #计数位数
DECLARE `value` VARCHAR(20);            #周期(D:按天清零;M:按月清零;Y:按年清零)默认按天
SELECT c.value INTO amount_num FROM config_billcode c WHERE c.sId='单据编号_计数位数' LIMIT 1;
SELECT c.value INTO `value` FROM config_billcode c WHERE c.sId='单据编号_计数清零' LIMIT 1;
SELECT c.value INTO year_num FROM config_billcode c WHERE c.sId='单据编号_年份位数' LIMIT 1;

#为编号中时间字段赋值
IF `value` = 'Y' THEN
SET num = year_num;
SELECT SUBSTRING(DATE_FORMAT(NOW(),'%Y'),5-year_num) INTO currentDate;
ELSEIF `value` = 'M' THEN
SET num = year_num+2;
SELECT SUBSTRING(DATE_FORMAT(NOW(),'%Y%m'),5-year_num) INTO currentDate;
ELSE
SET num = year_num+4;
SELECT SUBSTRING(DATE_FORMAT(NOW(),'%Y%m%d'),5-year_num) INTO currentDate;
END IF;

#拼接单据编号
SELECT IFNULL(vatNum,'') INTO oldOrderNo
FROM plan
WHERE SUBSTRING(vatNum,LENGTH(prefix)+2,num-1) = SUBSTRING(currentDate,2)
AND LENGTH(SUBSTRING(vatNum,LENGTH(prefix)+num+1))=amount_num
AND left(vatNum,length(prefix)) = prefix
ORDER BY right(vatNum,8)
DESC LIMIT 1;

IF oldOrderNo <> '' THEN
SET maxNo = CONVERT(SUBSTRING(oldOrderNo,0-amount_num),DECIMAL);
END IF;

SELECT CONCAT(prefix,currentDate,LPAD(maxNo+1,amount_num,'0')) INTO newOrderNo;
INSERT INTO debug_data(str_value) values (prefix),(currentDate),(maxNo),(amount_num);

RETURN newOrderNo;
END;

江阴天之然 源码从白玉兰拷贝来,该厂只有染色没有印花,采用一缸一张,所以要在白玉兰的基础上调整缸号生成规则。

  • config_billcode 的 “单据编号_计数位数” = 6
  • config_billcode 的 “单据编号_计数清零” = Y
  • 替换 GenerateCodeMapper.xml 中的方法 getPlanBillVatNum 调用的存储过程为 generate_plan_vatNo 该存储过程代码如下:
CREATE
    DEFINER = root@`%` FUNCTION generate_plan_vatNo(prefix VARCHAR(50)) RETURNS VARCHAR(100)
BEGIN
      #计划开单缸号生成的存储过程
    #传入参数为单据的前缀
    DECLARE currentDate VARCHAR(50); #日期号
    DECLARE newOrderNo VARCHAR(80); #最新的单据编号
    DECLARE oldOrderNo VARCHAR(80); #离本次最新的单据编号
    DECLARE maxNo BIGINT DEFAULT NULL; #当前周期内最大的计数
    DECLARE num INT(11); #时间字段位数
    DECLARE year_num INT(11); #年份位数
    DECLARE amount_num INT(11); #计数位数
    DECLARE `value` VARCHAR(20); #周期(D:按天清零;M:按月清零;Y:按年清零)默认按天
    SELECT c.value INTO amount_num FROM config_billcode c WHERE c.sId = '单据编号_计数位数' LIMIT 1;
    SELECT c.value INTO `value` FROM config_billcode c WHERE c.sId = '单据编号_计数清零' LIMIT 1;
    SELECT c.value INTO year_num FROM config_billcode c WHERE c.sId = '单据编号_年份位数' LIMIT 1;

    #为编号中时间字段赋值
    IF `value` = 'Y' THEN
        SET num = year_num;
        SELECT SUBSTRING(DATE_FORMAT(NOW(), '%Y'), 5 - year_num) INTO currentDate;
    ELSEIF `value` = 'M' THEN
        SET num = year_num + 2;
        SELECT SUBSTRING(DATE_FORMAT(NOW(), '%Y%m'), 5 - year_num) INTO currentDate;
    ELSE
        SET num = year_num + 4;
        SELECT SUBSTRING(DATE_FORMAT(NOW(), '%Y%m%d'), 5 - year_num) INTO currentDate;
    END IF;

    #拼接单据编号
    /*SELECT IFNULL(vatNum, '')
    INTO oldOrderNo
    FROM plan
    WHERE SUBSTRING(vatNum, LENGTH(prefix) + 2, num - 1) = SUBSTRING(currentDate, 2)
      AND
      # SUBSTRING(vatNum,1,LENGTH(prefix))=prefix AND
        LENGTH(SUBSTRING(vatNum, LENGTH(prefix) + num + 1)) = amount_num
    ORDER BY id DESC
    LIMIT 1;*/
    #查询当天的最近一次删除的编号
    /*IF oldOrderNo <> '' THEN SET maxNo = CONVERT(SUBSTRING(oldOrderNo, 0 - amount_num), DECIMAL); END IF;*/
    SET @date_prefix = substr(currentDate, 2);

    #创建临时表用于保存当天所有已开缸单
    DROP TEMPORARY TABLE IF EXISTS t_num,t_num_tmp;
    CREATE TEMPORARY TABLE t_num
    (
        pk_id       BIGINT AUTO_INCREMENT PRIMARY KEY,
        count_value BIGINT,
        create_time DATETIME
    );
    CREATE TEMPORARY TABLE t_num_tmp
    (
        pk_id       BIGINT AUTO_INCREMENT PRIMARY KEY,
        count_value BIGINT,
        create_time DATETIME
    );
    INSERT INTO t_num (count_value, create_time)
    SELECT DISTINCT cast(substr(vatNum, length(prefix) + num + 1, amount_num) AS DECIMAL(24)), createDate
    FROM plan
    WHERE substr(vatNum, length(prefix) + 2, num - 1) = @date_prefix
      AND SUBSTRING(vatNum, 1, LENGTH(prefix)) = prefix;
    INSERT INTO t_num_tmp (count_value, create_time)
    SELECT DISTINCT cast(substr(vatNum, length(prefix) + num + 1, amount_num) AS DECIMAL(24)), createDate
    FROM plan
    WHERE substr(vatNum, length(prefix) + 2, num - 1) = @date_prefix
      AND SUBSTRING(vatNum, 1, LENGTH(prefix)) = prefix;

    SELECT value_item.current_count
    INTO maxNo
    FROM (SELECT pk_id, count_value, count_value + 1 current_count
          FROM t_num
          WHERE DATE(create_time) = DATE(NOW())
            AND count_value + 1 NOT IN (SELECT count_value FROM t_num_tmp)
          ORDER BY count_value) value_item
    LIMIT 1;
    IF isnull(maxNo) THEN SELECT ifnull(max(count_value), 0) + 1 INTO maxNo FROM t_num; END IF;
    SELECT CONCAT(prefix, currentDate, LPAD(maxNo, amount_num, '0')) INTO newOrderNo;

    RETURN newOrderNo;
END;

与白坯的关系

概述

白坯单据的主从表 bpbillmainbpbilldetail
白坯加工入库的单据编号前缀是 BPR,计划领料、核销领料的单据编号都是 BP
字段 bpbilldetail.isOut 0计划扣库,2核销扣库
保存计划领料数据关联关系是:bpbillmain.vatNO = plan.vatNum
核销领料表 bpbilldetail 的关系是:bpbilldetail.vId = plan.id
缸单关联的工序表:craftdetail_plan
白坯领料时对应车数的表:detailbill_plan

恢复被作废的计划单提示:计划领料库存不够!无法恢复计划单!
是当前批次的白坯待扣库存数量不够 - 恢复缸单需要减少可用数量
检查当前待扣数量是否够用

计划领料

白坯明细表中的特征如下

  1. bpbilldetail.isOut = 0
  2. bpbilldetail.pId = 白坯入库明细主键
  3. bpbilldetail.vId = NULL

核销领料

白坯明细表中的特征如下

  1. isOut = 2
  2. bpbilldetail.pId = 白坯入库明细主键
  3. bpbilldetail.vId = plan.id (计划单主键)

单批所有缸单所有计划领料

下面 sql 是根据 plan_main.iid 查询一批生成的所有计划单的所有计划领料明细数据

select * from bpbilldetail where billCode in (
    select bpbillmain.billCode from bpbillmain where vatNO in (
        select vatNum from plan where mainid=29864
    )
);

缸单抬头名称

SELECT * FROM reportlets select * from g_printingdyeingname;

工序工艺

计划单JS文件 - src/main/webapp/web/MainPages/pages_SCJH/SC_PlanBill_Dye.js 在初始化函数中会根据工艺自动填充工序,在源码大概 102 行的 ajax1 填充工序标签页左边表格的数据 ajax2 填充右边表格的数据

自动领料

概述 计划单 JSP 页面中引用了 html 页面 - SC_DyePlanBill_Out.html JS - SC_PlanBill_outputbill.js 库存后台API - bpreposity/select_by_client mapper - BpRepositoryMapper.xml # findGreyFabricReposityByClientId 白坯库存使用了视图 r_bpBill

白玉兰 2022年2月16日 15:16:14 待扣库存表格数据的后台API - bpreposity/select_by_client 天之然 2023年9月23日 08:55:47 检查源码总结如下 计划单 SC_DyePlanBill.jsp 中嵌入外部页面 SC_DyePlanBill_Out.html 作为自动领料(这个逻辑应该是所有项目通用)。本页面3个表格从左到右,从上到下依次是:白坯库存表格(bp_out)、多选的待使用白坯(bp_out_wait)、右下角汇总车数表格(bp_out_total) 白坯库存 后台API :bpreposity/select_by_client,对应 mapper 中的 findGreyFabricReposityByClientId,SQL脚本如下

<select id="findGreyFabricReposityByClientId" resultType="account.entity.GreyFabricReposity">
  select * from r_bpBill
  <where>
    <if test="clientId != '' and clientId != null">
      and clientId=#{clientId,jdbcType=VARCHAR}
    </if>
    <if test="isShow != null">
      and (remain_kilo != 0 or remain_pairs != 0)
    </if>
  </where>
  order by id desc
</select>

注意视图 r_bpBill 以及后端 java 都没有自动计算“匹重”,在前端列定义中使用 avg_formatter 按照剩余公斤、匹数计算平均匹重,这个逻辑不对,应该使用入库的匹数、公斤计算“匹重”。

作废

  • 有两处可以作废:计划开单序时表的第一个标签页、计划单单据的工具栏
  • 作废的记录保存在表 plan_dtl

刷卡分类汇总表

menu.jsp : <a url="sc_swingcard_gather.do">刷卡分类汇总表</a>ModelAndViewController : @RequestMapping(value = "/sc_swingcard_gather.do") public ModelAndView SwingCardGather() throws Exception { jsp : web/MainPages/pages_SCJH/SC_SwingCard_category.jsp js : web/MainPages/pages_SCJH/SC_SwingCard_category.js 下面产量明细表是函数:swingCardDetail ,在行号:286 获取产量明细数据的请求是:swingcard/detail, 该请求的源码路径是:account.controller.report.SwingCardController.getSwingCardDetail 服务接口:account.service.CallService 的方法:getSwingCardDet 服务实现类:account.service.impl.CallServiceImpl 的方法:getSwingCardDet Mapper.xml : D:\Java\ideaProjs\pademis_ssm\src\main\java\account\entity\Mapping\CallMapper.xml 其中的方法:getSwingCardDet 使用的存储过程是:p_swingCardDet

上面表格的存储过程是:p_swingCardCls 银海印花项目JSP页面:WEB-INF/web/MainPages/pages_SCJH/SC_SwingCard_category.jsp 银海印花项目JS页面:web/MainPages/pages_SCJH/SC_SwingCard_category_v1.js

车间生产完工表

menu.jsp : <a url="SC_ProductSearch.do">车间生产完工表</a> account.controller.system.ModelAndViewController : 方法 ScProductSearch() jsp 页面:web/MainPages/pages_SCJH/SC_ProductSearch.jsp js 文件:web/MainPages/pages_SCJH/SC_ProductSearch.js

上面表格ID = MX 表格请求数据 API - finishedSwingCard/query,调用存储过程 - p_FinishedSwingCard 下面左边“刷卡明细”表格ID = ZH_grid1 上面表格行点击事件下执行“刷卡明细”数据请求,后台API - bpused/ghschedule/变量 该请求对应控制器 account.controller.report.BpUsedController 的方法 uspGhprocessQty 最终 mapper.xml 文件是 src/main/java/account/entity/Mapping/CallMapper.xml,使用的存储过程: Usp_GHProcessQty

kendoGrid请求URL:finishedSwingCard/query 控制器:account.controller.report.FinishedSwingCardController MAPPER文件:D:\Java\ideaProjs\pademis_ssm\src\main\java\account\entity\Mapping\CallMapper.xml 中的方法:getFinishedDetail 使用的存储过程:p_FinishedSwingCard

2022年3月11日 09:50:10 前两天李恢复了白玉兰厂里数据库,打开本报表右下角会报错,找到原因是配置表 g_config_oneint 中的项目 WEB应用_刷卡完工表是否可以查询全部 被设置0,更改为1即解决报错问题。 但是仍然有问题,该页面首次打开会一直转圈,修改了 account.service.impl.CallServiceImpl 下的方法 getFinishedDetail,将判断3个参数同时为 null 则返回 null 的代码注释掉,同时修改存储过程 p_FinishedSwingCard ,判断3个参数同时为 null 则设定 where 1=0

可视化进度表

注意工序名中不可有特殊符号,否则前端不显示数据 JSP - src/main/webapp/WEB-INF/web/MainPages/pages_SCJH/SC_order_process_progress_report.jsp JS - src/main/webapp/web/MainPages/pages_SCJH/SC_order_process_progress_report_v2.js 后台API - cjflowbill/getOrderProcessProgress 调用存储过程 - usp_getOrderProcessProgress

车间生产进度表

menu.jsp : 车间生产进度表 account.controller.system.ModelAndViewController:方法 sc_swipe_card jsp 页面:web/MainPages/pages_SCJH/SC_swipe_card.jsp js 文件:web/MainPages/pages_SCJH/SC_SwingCard_v3.js kendoGrid请求URL:v_swing_card/unfinished 控制器:account.controller.report.VSwingCardController 的方法:getUnfinishedSwingCard MAPPER文件:D:\Java\ideaProjs\pademis_ssm\src\main\java\account\entity\Mapping\CallMapper.xml 中的方法:getUnfinishedSwingCard 使用的存储过程:p_unfinishedSwingCard

批量删除职工产量

控制器:account.controller.report.GCjflowbilldetailController 的方法:deleteByProcessIds 服务接口:account.service.GCjflowbilldetailprocessService 的方法:deleteOutPutByProcessIds 服务实现类:account.service.impl.GCjflowbilldetailprocessServiceImpl 的方法:deleteOutPutByProcessIds

刷卡保存产量

account.bo.impl.GCjflowbilldetailpeopleBoImpl 的方法:update 传入参数类型是:GCjflowbilldetailprocess

染料入库单

nemu.jsp: <a url="rl_goodsdyebill.do">染料入库单</a> account.controller.system.ModelAndViewController:方法 RLGoodsDye jsp:web/MainPages/pages_RLPF/RL_GoodsDyeBill.jsp js:web/MainPages/pages_RLZJ/RL_GoodsDyeBill.js

客户订单

menu.jsp: <a url="orders.do">客户订单</a> account.controller.system.ModelAndViewController:方法 orders jsp:web/MainPages/pages_SCJH/SC_ClientOrders.jsp js:web/MainPages/pages_SCJH/SC_ClientOrders.js 禾达 - 白玉兰分支对应的 JS 文件:web/MainPages/pages_SCJH/SC_ClientOrders_v9.js 工具栏按钮“生成计划单”新打开的页面是: web/MainPages/pages_SCJH/SC_DyePlanBill 文件路径是: src/main/webapp/WEB-INF/web/MainPages/pages_SCJH/SC_DyePlanBill.jsp 主表数据使用 form 表单提交,新增单据请求的API:produce/client_order 是控制器 account.controller.forms.ClientOrderController 的方法:insert 修改客户订单的请求的API:produce/client_order_update 是控制器 account.controller.forms.ClientOrderController 的方法:updateProduceOrder

2021年12月15日 14:34:51 白玉兰 JSP - src/main/webapp/WEB-INF/web/MainPages/pages_SCJH/SC_ClientOrders.jsp JS - web/MainPages/pages_SCJH/SC_ClientOrders_v9.js 保存单据在 js 中的函数:btn_savedata 保存单据的控制器 - account.controller.forms.ClientOrderController 中的方法 insert

生成染印开单的计划单、普通计划单都是请求 toDyePlanBill.do 打开单据,传递的参数不同。 打开的 JSP - SC_DyePlanBill.jsp 保存单据在 js 中的函数:btn_savedata 自动领料使用了嵌入页面:web/MainPages/pages_SCJH/SC_DyePlanBill_Out.html

批量更新现有所有计划单的API:produce/update_toplan 搜索文件 SC_ClientOrders_v9.js 中的代码 saveData("produce/update_toplan");

提示

客户订单单据页面使用到的API: 在序时表中通过双击打开原单填充单据数据调用的API:produce/findMainBillByCode.do 新增单据:produce/client_order 修改单据:produce/client_order_update

客户订单序时表

控制器:toPlanBillProcess.do
控制器文件:account.controller.system.ModelAndViewController 的方法:toPlanBillProcess
JSP:web/MainPages/pages_SCJH/SC_ProcessBill.jsp
JS:web/MainPages/pages_SCJH/SC_ProcessBill_v1.js
2020年10月4日 12:57:54 查看源码将上面的 v1 js 调整为:
web/MainPages/pages_SCJH/SC_ProcessBill_v5.js
web/MainPages/pages_SCJH/SC_ProcessBill_printPage.js

乐达三 2022年1月27日 09:08:10
JSP - src/main/webapp/WEB-INF/web/MainPages/pages_SCJH/SC_ProcessBill.jsp
JS - src/main/webapp/web/MainPages/pages_SCJH/SC_ProcessBill_v4.js

朗迪 2022年1月3日 08:28:44
JSP - src/main/webapp/WEB-INF/web/MainPages/pages_SCJH/SC_ProcessBill.jsp
JS - src/main/webapp/web/MainPages/pages_SCJH/SC_ProcessBill_v3.js

明细序时表

明细表表格数据源请求:orderbill/detail
对明细表格进行初始化的函数是:MXXSB
对应的控制器:account.controller.report.COrderbillController 的方法:selectDetailByDateAndState
服务接口:account.service.CallService 的方法:getOrderDtl
服务实现类:account.service.impl.CallServiceImpl 的方法:getOrderDtl
DAO:account.dao.CallMapper 的方法:getOrderDtl
MAPPER:CallMapper.xml 的方法:getOrderDtl 使用的存储过程是:p_order_dtl

综合序时表

对综合表格进行初始化的函数是:ZHXSB
综合序时表后台API :orderbill/main
xml文件 CallMapper.xml 的方法 getOrderMain 调用存储过程 p_order_main