优化
This commit is contained in:
@@ -168,9 +168,6 @@ public interface ContainerBookingMapper extends BaseMapper<ContainerBookingEntit
|
||||
@Param("version") int version, @Param("operatorId") long operatorId,
|
||||
@Param("operatorName") String operatorName);
|
||||
|
||||
@Select("SELECT * FROM fl_container_booking WHERE container_no=#{containerNo} AND record_status='ACTIVE'")
|
||||
ContainerBookingEntity selectActiveByContainerNo(@Param("containerNo") String containerNo);
|
||||
|
||||
@Update("""
|
||||
UPDATE fl_container_booking SET unloading_completed_at=#{unloadingCompletedAt},
|
||||
unloading_photo_uploaded_at=#{photoUploadedAt}, estimated_empty_reported_at=#{estimatedEmptyReportedAt},
|
||||
|
||||
@@ -39,7 +39,7 @@ public final class OceanBookingDtos {
|
||||
}
|
||||
}
|
||||
|
||||
public record LinkCandidate(Long oceanBookingId, String bookingNo, Long requirementId,
|
||||
public record LinkCandidate(Long oceanBookingId, String bookingNo, String billOfLadingNo, Long requirementId,
|
||||
String containerType, BigDecimal capacityCbm, BigDecimal maxWeightKg,
|
||||
int requiredQuantity, long allocatedQuantity, long remainingQuantity,
|
||||
String customerName, String warehouseName, String channelName) {}
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@ public interface OceanBookingMapper extends BaseMapper<OceanBookingEntity> {
|
||||
|
||||
@Select("""
|
||||
<script>
|
||||
SELECT booking.id ocean_booking_id,booking.booking_no,requirement.id requirement_id,
|
||||
SELECT booking.id ocean_booking_id,booking.booking_no,booking.bill_of_lading_no,requirement.id requirement_id,
|
||||
requirement.container_type,requirement.capacity_cbm,requirement.max_weight_kg,
|
||||
requirement.quantity required_quantity,
|
||||
COALESCE(allocated.allocated_quantity,0) allocated_quantity,
|
||||
|
||||
+6
-3
@@ -38,6 +38,12 @@ public class OceanBookingRepository {
|
||||
}
|
||||
public OceanBookingEntity find(long id) { return bookings.selectById(id); }
|
||||
public OceanBookingEntity findForUpdate(long id) { return bookings.selectForUpdate(id); }
|
||||
public boolean billOfLadingNoExists(String billOfLadingNo, Long excludedId) {
|
||||
if (billOfLadingNo == null) return false;
|
||||
return bookings.selectCount(new LambdaQueryWrapper<OceanBookingEntity>()
|
||||
.eq(OceanBookingEntity::getBillOfLadingNo, billOfLadingNo)
|
||||
.ne(excludedId != null, OceanBookingEntity::getId, excludedId)) > 0;
|
||||
}
|
||||
public void insert(OceanBookingEntity value) { bookings.insert(value); }
|
||||
public int transition(long id, String from, String to, int version, long operatorId, String operatorName) {
|
||||
return bookings.transition(id, from, to, version, operatorId, operatorName);
|
||||
@@ -102,9 +108,6 @@ public class OceanBookingRepository {
|
||||
public void replaceParties(long id, List<OceanBookingPartyEntity> values) { parties.delete(new LambdaQueryWrapper<OceanBookingPartyEntity>().eq(OceanBookingPartyEntity::getOceanBookingId, id)); values.forEach(parties::insert); }
|
||||
public void replaceRequirements(long id, List<OceanBookingContainerRequirementEntity> values) { requirements.delete(new LambdaQueryWrapper<OceanBookingContainerRequirementEntity>().eq(OceanBookingContainerRequirementEntity::getOceanBookingId, id)); values.forEach(requirements::insert); }
|
||||
public OceanBookingContainerRequirementEntity requirement(long id, long requirementId) { return requirements.selectOne(new LambdaQueryWrapper<OceanBookingContainerRequirementEntity>().eq(OceanBookingContainerRequirementEntity::getOceanBookingId, id).eq(OceanBookingContainerRequirementEntity::getId, requirementId)); }
|
||||
public boolean containerNoExists(String containerNo) {
|
||||
return containerBookings.containerNoExists(containerNo, null);
|
||||
}
|
||||
public void insertContainer(ContainerBookingEntity value) { containerBookings.insert(value); }
|
||||
public void insert(OceanBookingContainerAllocationEntity value) { allocations.insert(value); }
|
||||
public int reassignAllocation(long sourceId, long targetId) {
|
||||
|
||||
+16
-2
@@ -24,6 +24,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
import feign.FeignException;
|
||||
@@ -110,9 +111,11 @@ public class OceanBookingService {
|
||||
value.setBookingNo(documentNumbers.next("OB"));
|
||||
value.setStatus(OceanBookingStatus.DRAFT.name());
|
||||
copy(value, request.data(), resolved);
|
||||
requireUniqueBillOfLadingNo(value.getBillOfLadingNo(), null);
|
||||
value.setCreatedBy(operatorId); value.setCreatedByName(operatorName);
|
||||
value.setUpdatedBy(operatorId); value.setUpdatedByName(operatorName); value.setVersion(0);
|
||||
repository.insert(value);
|
||||
try { repository.insert(value); }
|
||||
catch (DuplicateKeyException exception) { throw duplicateBillOfLadingNo(); }
|
||||
repository.replaceParties(value.getId(), parties(value.getId(), request.data().parties()));
|
||||
List<OceanBookingContainerRequirementEntity> requirements = requirements(
|
||||
value.getId(), request.data().containerRequirements());
|
||||
@@ -132,7 +135,10 @@ public class OceanBookingService {
|
||||
validateDraftStructure(request.data());
|
||||
ResolvedDraft resolved = resolveDraft(request.data());
|
||||
copy(before, request.data(), resolved);
|
||||
if (repository.updateDraft(before, request.expectedVersion(), operatorId, operatorName) != 1) throw concurrent();
|
||||
requireUniqueBillOfLadingNo(before.getBillOfLadingNo(), id);
|
||||
try {
|
||||
if (repository.updateDraft(before, request.expectedVersion(), operatorId, operatorName) != 1) throw concurrent();
|
||||
} catch (DuplicateKeyException exception) { throw duplicateBillOfLadingNo(); }
|
||||
repository.replaceParties(id, parties(id, request.data().parties()));
|
||||
repository.replaceRequirements(id, requirements(id, request.data().containerRequirements()));
|
||||
OceanBookingEntity after = required(id);
|
||||
@@ -294,6 +300,14 @@ public class OceanBookingService {
|
||||
v.setRemark(trim(d.remark()));
|
||||
}
|
||||
|
||||
private void requireUniqueBillOfLadingNo(String billOfLadingNo, Long excludedId) {
|
||||
if (repository.billOfLadingNoExists(billOfLadingNo, excludedId)) throw duplicateBillOfLadingNo();
|
||||
}
|
||||
|
||||
private static BizException duplicateBillOfLadingNo() {
|
||||
return conflict("提单号已存在,请检查是否重复创建订舱");
|
||||
}
|
||||
|
||||
private void validateMasterData(OceanBookingEntity booking) {
|
||||
resolveCustomer(booking.getCustomerId(), booking.getCustomerName());
|
||||
resolveCarrier(booking.getShippingCompanyId(), booking.getShippingCompanyName(), booking.getCarrierCode());
|
||||
|
||||
@@ -22,9 +22,10 @@ public class ContainerRepository {
|
||||
public ContainerBookingEntity findForUpdate(long id) { return mapper.selectBookingForUpdate(id); }
|
||||
public ContainerBookingEntity findActiveForUpdate(long id) { return mapper.selectActiveBookingForUpdate(id); }
|
||||
public boolean departed(long id) { return mapper.hasActiveOutboundDeparture(id) > 0; }
|
||||
public boolean containerNoExists(String no, Long excludedId) {
|
||||
public boolean containerNoExists(long oceanBookingId, String no, Long excludedId) {
|
||||
if (no == null) return false;
|
||||
return mapper.selectCount(new LambdaQueryWrapper<ContainerBookingEntity>()
|
||||
.eq(ContainerBookingEntity::getOceanBookingId, oceanBookingId)
|
||||
.eq(ContainerBookingEntity::getContainerNo, no)
|
||||
.ne(excludedId != null, ContainerBookingEntity::getId, excludedId)) > 0;
|
||||
}
|
||||
|
||||
@@ -93,7 +93,9 @@ public class ContainerService {
|
||||
if (requirement == null) throw new BizException(ResultCode.NOT_FOUND, "订舱箱型需求不存在");
|
||||
long allocated = oceanBookings.activeLinkedCount(request.oceanBookingId(), request.requirementId());
|
||||
if (allocated >= requirement.getQuantity()) throw conflict("该订舱箱型需求已达到数量上限");
|
||||
if (containerNo != null && repository.containerNoExists(containerNo, id)) throw conflict("集装箱号已存在");
|
||||
if (containerNo != null && repository.containerNoExists(request.oceanBookingId(), containerNo, id)) {
|
||||
throw conflict("当前提单下集装箱号已存在");
|
||||
}
|
||||
if (!java.util.Objects.equals(container.getWarehouseId(), booking.getWarehouseId())
|
||||
|| !java.util.Objects.equals(container.getChannelGroupCode(), booking.getChannelCode())
|
||||
|| !java.util.Objects.equals(container.getContainerType(), requirement.getContainerType())) {
|
||||
@@ -105,7 +107,7 @@ public class ContainerService {
|
||||
throw conflict("真实订舱柜已被消费或货柜版本发生变化,请刷新后重试");
|
||||
}
|
||||
} catch (DuplicateKeyException exception) {
|
||||
throw conflict("集装箱号已存在");
|
||||
throw conflict("当前提单下集装箱号已存在");
|
||||
}
|
||||
OceanBookingContainerAllocationEntity allocation = new OceanBookingContainerAllocationEntity(); allocation.setId(IdWorker.getId()); allocation.setOceanBookingId(request.oceanBookingId()); allocation.setRequirementId(request.requirementId()); allocation.setContainerBookingId(id); allocation.setAllocatedBy(operatorId); allocation.setAllocatedByName(operatorName); allocation.setAllocatedAt(LocalDateTime.now()); oceanBookings.insert(allocation);
|
||||
return required(id);
|
||||
@@ -126,13 +128,15 @@ public class ContainerService {
|
||||
throw conflict("已进入PDA、证据、单证或不可逆装柜阶段,不能补录真实柜号");
|
||||
}
|
||||
String containerNo = Iso6346ContainerNumber.require(requestedContainerNo);
|
||||
if (repository.containerNoExists(containerNo, id)) throw conflict("集装箱号已存在");
|
||||
if (repository.containerNoExists(container.getOceanBookingId(), containerNo, id)) {
|
||||
throw conflict("当前提单下集装箱号已存在");
|
||||
}
|
||||
try {
|
||||
if (repository.assignRealContainerNo(id, containerNo, expectedVersion, operatorId, operatorName) != 1) {
|
||||
throw conflict("真实柜号已被补录或货柜版本发生变化,请刷新后重试");
|
||||
}
|
||||
} catch (DuplicateKeyException exception) {
|
||||
throw conflict("集装箱号已存在");
|
||||
throw conflict("当前提单下集装箱号已存在");
|
||||
}
|
||||
return required(id);
|
||||
}
|
||||
|
||||
@@ -463,9 +463,10 @@ public class LoadingListService {
|
||||
&& java.util.Objects.equals(before.getVoyageNo(), voyageNo)) {
|
||||
return repository.preloadDetail(before);
|
||||
}
|
||||
if (containerNo != null
|
||||
&& containerRepository.containerNoExists(containerNo, before.getContainerBookingId())) {
|
||||
throw conflict("集装箱号已存在");
|
||||
if (containerNo != null && before.getOceanBookingId() != null
|
||||
&& containerRepository.containerNoExists(before.getOceanBookingId(), containerNo,
|
||||
before.getContainerBookingId())) {
|
||||
throw conflict("当前提单下集装箱号已存在");
|
||||
}
|
||||
try {
|
||||
int updated = initialContainerFill
|
||||
@@ -477,7 +478,7 @@ public class LoadingListService {
|
||||
throw conflict("预装计划、PDA领取或物理作业状态已变化,请刷新后重试");
|
||||
}
|
||||
} catch (DuplicateKeyException exception) {
|
||||
throw conflict("集装箱号已存在");
|
||||
throw conflict("当前提单下集装箱号已存在");
|
||||
}
|
||||
repository.appendHistory(planId, operationId, "UPDATE_PRELOAD_TRANSPORT",
|
||||
before.getPlanStatus(), before.getPlanStatus(), json(snapshot(before)),
|
||||
|
||||
Reference in New Issue
Block a user