fix(firstleg): allow customs view for empty loading plan
This commit is contained in:
+2
-1
@@ -22,7 +22,8 @@ public final class ContainerCustomsDtos {
|
||||
boolean frozen, FileView completion) {}
|
||||
|
||||
public record ContainerView(long aggregateId, long loadingPlanId, long containerBookingId,
|
||||
String planNo, String cabinetNo, String containerNo, String status, String merchantStatus,
|
||||
String planNo, String cabinetNo, String containerNo, String status, boolean hasActualCargo,
|
||||
String merchantStatus,
|
||||
int version, int taxRefundCount, int coveredTaxRefundCount,
|
||||
List<InboundView> inbounds, List<DocumentView> documents,
|
||||
LocalDateTime startedAt, LocalDateTime completedAt) {}
|
||||
|
||||
+11
@@ -34,6 +34,15 @@ public interface ContainerCustomsMapper {
|
||||
""")
|
||||
List<InboundRow> planInbounds(@Param("planId") long planId);
|
||||
|
||||
@Select("""
|
||||
SELECT p.id loadingPlanId,p.plan_no planNo,p.container_booking_id containerBookingId,
|
||||
p.plan_status loadingPlanStatus,b.cabinet_no cabinetNo,b.container_no containerNo
|
||||
FROM fl_loading_plan p
|
||||
JOIN fl_container_booking b ON b.id=p.container_booking_id AND b.record_status='ACTIVE'
|
||||
WHERE p.id=#{planId}
|
||||
""")
|
||||
PlanRow plan(@Param("planId") long planId);
|
||||
|
||||
@Select("""
|
||||
SELECT p.id FROM fl_loading_plan p
|
||||
JOIN fl_loading_plan_item item ON item.loading_plan_id=p.id AND item.deleted=0
|
||||
@@ -331,6 +340,8 @@ public interface ContainerCustomsMapper {
|
||||
record InboundRow(Long loadingPlanId,String planNo,Long containerBookingId,String loadingPlanStatus,
|
||||
String cabinetNo,String containerNo,Long inboundId,Long orderId,String orderNo,String inboundCode,
|
||||
Long tenantId,String customerName,String taxMode) {}
|
||||
record PlanRow(Long loadingPlanId,String planNo,Long containerBookingId,String loadingPlanStatus,
|
||||
String cabinetNo,String containerNo) {}
|
||||
record ContainerRow(Long id,Long loadingPlanId,Long containerBookingId,String status,Long startedBy,
|
||||
String startedByName,LocalDateTime startedAt,Long completedBy,String completedByName,
|
||||
LocalDateTime completedAt,LocalDateTime createdAt,LocalDateTime updatedAt,Integer version) {}
|
||||
|
||||
+28
-10
@@ -155,6 +155,7 @@ public class ContainerCustomsService {
|
||||
CommandRow replay = claim(operatorId, action, key, requestHash);
|
||||
if (replay != null) return platformView(planId);
|
||||
ensure(planId);
|
||||
if (actualPlanRows(planId).isEmpty()) throw conflict("当前装柜计划没有实际货物,无需报关");
|
||||
ContainerRow locked = mapper.lockContainer(planId);
|
||||
if (locked == null || !READY.equals(locked.status())) throw conflict("当前柜报关资料尚未齐全或已开始报关");
|
||||
if (!Objects.equals(locked.version(), request.expectedVersion())) throw concurrent();
|
||||
@@ -219,7 +220,8 @@ public class ContainerCustomsService {
|
||||
ContainerRow container = mapper.lockContainer(planId);
|
||||
if (container == null || !DECLARING.equals(container.status())) throw conflict("当前柜不在报关中");
|
||||
if (!Objects.equals(container.version(), request.expectedVersion())) throw concurrent();
|
||||
List<InboundRow> actual=planRows(planId);
|
||||
List<InboundRow> actual=actualPlanRows(planId);
|
||||
if(actual.isEmpty())throw conflict("当前装柜计划没有实际货物,无需报关");
|
||||
if(actual.stream().anyMatch(row->!"BUY_DECLARATION".equals(row.taxMode())))throw conflict("全买单柜完成只允许全部实际行均为BUY_DECLARATION");
|
||||
completeContainer(container, operatorId, operatorName, request.remark());
|
||||
completeCommand(operatorId, action, key, container.id());
|
||||
@@ -245,11 +247,11 @@ public class ContainerCustomsService {
|
||||
}
|
||||
|
||||
private ContainerRow ensure(long planId) {
|
||||
List<InboundRow> rows = planRows(planId);
|
||||
InboundRow first = rows.get(0);
|
||||
if (!"COMPLETED".equals(first.loadingPlanStatus())) throw conflict("装柜完成后才能处理报关资料");
|
||||
List<InboundRow> rows = actualPlanRows(planId);
|
||||
PlanRow plan = rows.isEmpty() ? requiredPlan(planId) : plan(rows.get(0));
|
||||
if (!"COMPLETED".equals(plan.loadingPlanStatus())) throw conflict("装柜完成后才能处理报关资料");
|
||||
boolean refund = rows.stream().anyMatch(row -> "TAX_REFUND".equals(row.taxMode()));
|
||||
mapper.insertContainer(IdWorker.getId(), planId, first.containerBookingId(), refund ? WAITING : READY);
|
||||
mapper.insertContainer(IdWorker.getId(), planId, plan.containerBookingId(), refund ? WAITING : READY);
|
||||
return refresh(planId);
|
||||
}
|
||||
|
||||
@@ -283,11 +285,27 @@ public class ContainerCustomsService {
|
||||
}
|
||||
|
||||
private List<InboundRow> planRows(long planId) {
|
||||
List<InboundRow> rows = mapper.planInbounds(planId);
|
||||
List<InboundRow> rows = actualPlanRows(planId);
|
||||
if (rows == null || rows.isEmpty()) throw notFound("未找到当前装柜计划的实际货物明细");
|
||||
return rows;
|
||||
}
|
||||
|
||||
private List<InboundRow> actualPlanRows(long planId) {
|
||||
List<InboundRow> rows = mapper.planInbounds(planId);
|
||||
return rows == null ? List.of() : rows;
|
||||
}
|
||||
|
||||
private PlanRow requiredPlan(long planId) {
|
||||
PlanRow plan = mapper.plan(planId);
|
||||
if (plan == null) throw notFound("装柜计划不存在或不可用");
|
||||
return plan;
|
||||
}
|
||||
|
||||
private PlanRow plan(InboundRow row) {
|
||||
return new PlanRow(row.loadingPlanId(), row.planNo(), row.containerBookingId(), row.loadingPlanStatus(),
|
||||
row.cabinetNo(), row.containerNo());
|
||||
}
|
||||
|
||||
private List<InboundRow> validateScope(long planId, long tenantId, List<Long> inboundIds) {
|
||||
if (inboundIds == null || inboundIds.isEmpty() || inboundIds.size() > 200) throw bad("至少选择一个且最多200个入仓码");
|
||||
Set<Long> requested = new LinkedHashSet<>(inboundIds);
|
||||
@@ -304,7 +322,8 @@ public class ContainerCustomsService {
|
||||
}
|
||||
|
||||
private ContainerView view(ContainerRow container, Long tenantId, boolean merchant) {
|
||||
List<InboundRow> rows = planRows(container.loadingPlanId());
|
||||
List<InboundRow> rows = actualPlanRows(container.loadingPlanId());
|
||||
PlanRow plan = rows.isEmpty() ? requiredPlan(container.loadingPlanId()) : plan(rows.get(0));
|
||||
List<DocumentRow> documents = mapper.documents(container.id(), tenantId);
|
||||
Set<Long> covered = documents.stream().flatMap(doc -> mapper.scopes(doc.id()).stream()).map(ScopeRow::inboundId).collect(Collectors.toSet());
|
||||
List<InboundRow> visibleRows=rows.stream().filter(row -> tenantId == null || (row.tenantId().equals(tenantId)&&"TAX_REFUND".equals(row.taxMode()))).toList();
|
||||
@@ -315,9 +334,8 @@ public class ContainerCustomsService {
|
||||
int refund = (int) visibleRows.stream().filter(row -> "TAX_REFUND".equals(row.taxMode())).count();
|
||||
int coveredRefund = (int) visibleRows.stream().filter(row -> covered.contains(row.inboundId())).count();
|
||||
String merchantStatus=tenantId==null?null:merchantStatus(container.status(),refund,coveredRefund);
|
||||
InboundRow first = rows.get(0);
|
||||
return new ContainerView(container.id(), container.loadingPlanId(), container.containerBookingId(), first.planNo(),
|
||||
first.cabinetNo(), first.containerNo(), container.status(), merchantStatus, container.version(), refund, coveredRefund,
|
||||
return new ContainerView(container.id(), container.loadingPlanId(), container.containerBookingId(), plan.planNo(),
|
||||
plan.cabinetNo(), plan.containerNo(), container.status(), !rows.isEmpty(), merchantStatus, container.version(), refund, coveredRefund,
|
||||
inbounds, documentViews, container.startedAt(), container.completedAt());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user