🐛 待回单确认下拒绝补录打卡

This commit is contained in:
2026-10-22 13:44:06 +08:00
parent 311e7ff94a
commit 6de80d2bb2
2 changed files with 60 additions and 0 deletions
@@ -531,6 +531,12 @@ public class WaybillServiceImpl extends BaseServiceImpl<WaybillMapper, Waybill>
}
// 只有显式传 false 才是取消打卡,未传按已打卡处理
boolean punched = !Boolean.FALSE.equals(request.getPunched());
// 待回单确认的运单司机已无待打卡节点,再补一条打卡流水与状态含义矛盾;
// 漏打的出路是先取消该节点的打卡退回进行中(punched=false),再重新补录。
if (punched && WaybillProcessSupport.STATUS_PENDING_RETURN_CONFIRM
.equalsIgnoreCase(waybill.getBusinessStatus())) {
throw new ServiceException("运单待业务员确认回单,不能补录打卡");
}
if (ENROUTE_PUNCH_TYPE.equalsIgnoreCase(TransportBusinessSupport.trimToEmpty(request.getType()))) {
return saveEnroutePunchRecord(waybill, request, punched);
}
@@ -18,6 +18,7 @@ import org.springblade.transport.pojo.dto.WaybillPunchRecordSaveRequest;
import org.springblade.transport.pojo.entity.Waybill;
import org.springblade.transport.pojo.entity.WaybillEnroutePunch;
import org.springblade.transport.pojo.entity.WaybillNodePunch;
import org.springblade.transport.support.WaybillProcessSupport;
import java.lang.reflect.Field;
import java.util.ArrayList;
@@ -165,6 +166,59 @@ class WaybillPunchRecordSaveTest {
verify(nodePunchMapper, never()).updateById(any(WaybillNodePunch.class));
}
@Test
@DisplayName("待回单确认:补录打卡被拒——司机已无待打卡,漏打应先取消打卡退回进行中")
void rejectBackfillOnPendingReturnConfirm() {
Waybill waybill = waybill();
waybill.setBusinessStatus(WaybillProcessSupport.STATUS_PENDING_RETURN_CONFIRM);
when(waybillMapper.selectById(WAYBILL_ID)).thenReturn(waybill);
when(nodePunchMapper.selectList(any())).thenReturn(List.of());
WaybillPunchRecordSaveRequest request = request("node", "load", "装货");
request.setPunched(true);
ServiceException exception = assertThrows(ServiceException.class,
() -> service.savePunchRecord(request));
assertEquals("运单待业务员确认回单,不能补录打卡", exception.getMessage());
verify(nodePunchMapper, never()).insert(any(WaybillNodePunch.class));
}
@Test
@DisplayName("待回单确认:取消打卡仍放行——那是退回进行中的唯一路径")
void keepCancelPunchOnPendingReturnConfirm() {
Waybill waybill = waybill();
waybill.setBusinessStatus(WaybillProcessSupport.STATUS_PENDING_RETURN_CONFIRM);
when(waybillMapper.selectById(WAYBILL_ID)).thenReturn(waybill);
when(nodePunchMapper.selectList(any())).thenReturn(List.of(nodePunch(7001L, "load", "装货")));
WaybillPunchRecordSaveRequest request = request("node", "load", "装货");
request.setPunched(false);
assertTrue(service.savePunchRecord(request));
ArgumentCaptor<Collection<Long>> captor = ArgumentCaptor.forClass(Collection.class);
verify(nodePunchMapper).deleteBatchIds(captor.capture());
assertEquals(Set.of(7001L), new HashSet<>(captor.getValue()));
}
@Test
@DisplayName("已完成运单仍可补录——门禁只对待回单确认生效")
void keepBackfillOnCompletedWaybill() {
Waybill waybill = waybill();
waybill.setBusinessStatus("completed");
when(waybillMapper.selectById(WAYBILL_ID)).thenReturn(waybill);
when(nodePunchMapper.selectList(any())).thenReturn(List.of());
WaybillPunchRecordSaveRequest request = request("node", "load", "装货");
request.setPunched(true);
request.setPunchTime("2026-10-06 09:30:00");
assertTrue(service.savePunchRecord(request));
verify(nodePunchMapper).insert(any(WaybillNodePunch.class));
}
@Test
@DisplayName("接单节点:补录与取消打卡都拒绝——它的完成由运单的接单事实决定")
void rejectAcceptNodePunchEdit() {