fix(procurement): read MySQL fulfillment timestamps with JDBC types
This commit is contained in:
+1
-1
@@ -107,7 +107,7 @@ public class ProcurementChargeService {
|
||||
}
|
||||
private Snapshot snapshot(OverseasProcurementOrder order) {
|
||||
Object at=lifecycle.flow(order.getId()).get("charges_confirmed_at");
|
||||
return new Snapshot(order.getOrderNo(),order.getVersion(),order.getStatus(),at==null?null:((java.sql.Timestamp)at).toLocalDateTime(),
|
||||
return new Snapshot(order.getOrderNo(),order.getVersion(),order.getStatus(),(java.time.LocalDateTime)at,
|
||||
finance.all(order.getId()).stream().map(f->new Fee(f,finance.sourceLinked(f))).toList());
|
||||
}
|
||||
}
|
||||
|
||||
+9
-3
@@ -17,7 +17,6 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
import java.math.BigDecimal;
|
||||
import java.security.MessageDigest;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HexFormat;
|
||||
import java.util.List;
|
||||
@@ -29,6 +28,13 @@ import java.util.Set;
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ProcurementLifecycleService {
|
||||
// Read SQL DATETIME/TIMESTAMP through JDBC 4.2, independently of each driver's default getObject type.
|
||||
static final org.springframework.jdbc.core.ColumnMapRowMapper FACT_ROW = new org.springframework.jdbc.core.ColumnMapRowMapper() {
|
||||
@Override protected Object getColumnValue(java.sql.ResultSet rs,int index) throws java.sql.SQLException {
|
||||
if(rs.getMetaData().getColumnType(index)==java.sql.Types.TIMESTAMP) return rs.getObject(index,LocalDateTime.class);
|
||||
return super.getColumnValue(rs,index);
|
||||
}
|
||||
};
|
||||
private final OverseasProcurementOrderMapper orders;
|
||||
private final OverseasProcurementFileMapper files;
|
||||
private final ProcurementWarehouseDirectory warehouses;
|
||||
@@ -130,7 +136,7 @@ public class ProcurementLifecycleService {
|
||||
}
|
||||
var budget=budget(order);
|
||||
if(budget.amount()==null) issue="客户货款预算尚未明确,请取得凭证并完成预算核验";
|
||||
var businessDate=((Timestamp)flow.get("purchased_at")).toLocalDateTime().toLocalDate();
|
||||
var businessDate=((LocalDateTime)flow.get("purchased_at")).toLocalDate();
|
||||
if(issue==null) {
|
||||
try {
|
||||
var payment=converter.convert(String.valueOf(flow.get("purchase_currency")),(BigDecimal)flow.get("purchase_amount"),businessDate);
|
||||
@@ -191,7 +197,7 @@ public class ProcurementLifecycleService {
|
||||
return new Outcome(order.getOrderNo(),order.getVersion(),order.getStatus(),purchaseStatus(order));
|
||||
}
|
||||
Map<String,Object> flow(long orderId) {
|
||||
var rows=jdbc.queryForList("SELECT * FROM ll_procurement_flow WHERE order_id=?",orderId);
|
||||
var rows=jdbc.query("SELECT * FROM ll_procurement_flow WHERE order_id=?",FACT_ROW,orderId);
|
||||
return rows.isEmpty()?Map.of():rows.get(0);
|
||||
}
|
||||
void ensureFlow(OverseasProcurementOrder order) {
|
||||
|
||||
+3
-4
@@ -11,7 +11,6 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import static com.baiyue.lastleg.procurement.service.ProcurementLifecycleService.*;
|
||||
@@ -112,10 +111,10 @@ public class ProcurementPhysicalService {
|
||||
if(flow.get("actual_warehouse_id")!=null && ((Number)flow.get("actual_warehouse_id")).longValue()!=request.warehouseId()) throw conflict("本单实际收货仓已冻结,不支持转仓");
|
||||
jdbc.update("UPDATE ll_procurement_flow SET actual_warehouse_id=?,actual_warehouse_code=?,actual_warehouse_name=? WHERE order_id=?",
|
||||
warehouse.warehouseId(),warehouse.warehouseCode(),warehouse.warehouseName(),order.getId());
|
||||
originAt=((Timestamp)flow.get("purchased_at")).toLocalDateTime();
|
||||
originAt=((LocalDateTime)flow.get("purchased_at"));
|
||||
} else {
|
||||
if(request.warehouseId()!=null) throw bad("国内实收不应指定海外仓");
|
||||
originAt=((Timestamp)flow.get("overseas_shipped_at")).toLocalDateTime();
|
||||
originAt=((LocalDateTime)flow.get("overseas_shipped_at"));
|
||||
}
|
||||
if(request.receivedAt().isBefore(originAt)) throw bad("实收时间不能早于来源购买或国际交寄时间");
|
||||
long counted=received(order.getId(),request.leg(),request.sourceCartonId()).stream()
|
||||
@@ -293,7 +292,7 @@ public class ProcurementPhysicalService {
|
||||
return new Snapshot(orderNo,version,status,receipts,dispositions,((Number)manifest.get("version")).intValue(),String.valueOf(manifest.get("status")),cartons);
|
||||
}
|
||||
Map<String,Object> currentManifest(long orderId) {
|
||||
var rows=jdbc.queryForList("SELECT * FROM ll_procurement_manifest WHERE order_id=? AND status<>'SUPERSEDED' ORDER BY version DESC LIMIT 1",orderId);
|
||||
var rows=jdbc.query("SELECT * FROM ll_procurement_manifest WHERE order_id=? AND status<>'SUPERSEDED' ORDER BY version DESC LIMIT 1",ProcurementLifecycleService.FACT_ROW,orderId);
|
||||
return rows.isEmpty()?null:rows.get(0);
|
||||
}
|
||||
long goodTotal(long orderId,Leg leg){return received(orderId,leg,null,true).stream().mapToLong(ReceiptRow::goodQuantity).reduce(0,ProcurementPhysicalService::add);}
|
||||
|
||||
+3
-3
@@ -72,11 +72,11 @@ public class ProcurementQueryService {
|
||||
var manifest=physical.currentManifest(order.getId());
|
||||
boolean confirmed=manifest!=null && "CONFIRMED".equals(manifest.get("status"));
|
||||
progress.add(4,new Progress("packing_confirmed","装箱确认",confirmed?date(manifest.get("confirmed_at")):null));
|
||||
var labelDates=confirmed?jdbc.queryForList("SELECT l.id,l.created_at FROM ll_procurement_label_set l WHERE l.order_id=? AND l.leg='OVERSEAS' AND l.manifest_id=? ORDER BY l.version DESC LIMIT 1",order.getId(),manifest.get("id")):List.<Map<String,Object>>of();
|
||||
var labelDates=confirmed?jdbc.query("SELECT l.id,l.created_at FROM ll_procurement_label_set l WHERE l.order_id=? AND l.leg='OVERSEAS' AND l.manifest_id=? ORDER BY l.version DESC LIMIT 1",ProcurementLifecycleService.FACT_ROW,order.getId(),manifest.get("id")):List.<Map<String,Object>>of();
|
||||
progress.add(5,new Progress("international_labels","国际面单上传",labelDates.isEmpty()?null:date(labelDates.get(0).get("created_at"))));
|
||||
LocalDateTime applied=null;
|
||||
if(!labelDates.isEmpty()) {
|
||||
var states=jdbc.queryForMap("SELECT COUNT(*) AS total,SUM(CASE WHEN applied_at IS NULL THEN 1 ELSE 0 END) AS missing,MAX(applied_at) AS applied_at FROM ll_procurement_label_item WHERE label_set_id=?",labelDates.get(0).get("id"));
|
||||
var states=jdbc.query("SELECT COUNT(*) AS total,SUM(CASE WHEN applied_at IS NULL THEN 1 ELSE 0 END) AS missing,MAX(applied_at) AS applied_at FROM ll_procurement_label_item WHERE label_set_id=?",ProcurementLifecycleService.FACT_ROW,labelDates.get(0).get("id")).get(0);
|
||||
if(((Number)states.get("total")).longValue()>0 && ((Number)states.get("missing")).longValue()==0)applied=date(states.get("applied_at"));
|
||||
}
|
||||
progress.add(6,new Progress("labels_applied","全部箱贴单",applied));
|
||||
@@ -128,5 +128,5 @@ public class ProcurementQueryService {
|
||||
}
|
||||
private static void action(List<Action> result,Set<String> permissions,String key,String label,String suffix,String block){String code="platform:overseas-business:purchase:"+suffix;String reason=permissions==null || !permissions.contains(code)?"无此操作权限":block;result.add(new Action(key,label,code,reason==null,reason));}
|
||||
private static String reason(Runnable action){try{action.run();return null;}catch(org.springframework.web.server.ResponseStatusException e){return e.getReason();}}
|
||||
private static LocalDateTime date(Object value){return value==null?null:((java.sql.Timestamp)value).toLocalDateTime();}
|
||||
private static LocalDateTime date(Object value){return (LocalDateTime)value;}
|
||||
}
|
||||
|
||||
+2
-3
@@ -12,7 +12,6 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import java.math.BigDecimal;
|
||||
import java.security.MessageDigest;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import static com.baiyue.lastleg.procurement.service.ProcurementLifecycleService.*;
|
||||
@@ -115,7 +114,7 @@ public class ProcurementTransportService {
|
||||
var labels=validLabels(order,Leg.OVERSEAS,request.labelVersion());
|
||||
if(request.appliedAt()==null || request.appliedAt().isAfter(LocalDateTime.now()))throw bad("请填写真实贴单时间");
|
||||
var flow=lifecycle.flow(order.getId());
|
||||
if(request.appliedAt().isBefore(((Timestamp)flow.get("overseas_received_at")).toLocalDateTime()))throw bad("贴单时间不能早于海外收货完成");
|
||||
if(request.appliedAt().isBefore(((LocalDateTime)flow.get("overseas_received_at"))))throw bad("贴单时间不能早于海外收货完成");
|
||||
if(request.cartonIds()==null || request.cartonIds().isEmpty() || new HashSet<>(request.cartonIds()).size()!=request.cartonIds().size())throw bad("请选择不重复的实际贴单箱");
|
||||
for(long carton:request.cartonIds()) {
|
||||
var label=labels.labels().stream().filter(l->l.cartonId()==carton).findFirst().orElseThrow(()->bad("贴单箱不属于当前面单"));
|
||||
@@ -154,7 +153,7 @@ public class ProcurementTransportService {
|
||||
if(request.leg()==Leg.OVERSEAS) {
|
||||
if(labels.labels().stream().anyMatch(l->request.shippedAt().isBefore(l.appliedAt())))throw bad("交寄时间不能早于贴单时间");
|
||||
} else {
|
||||
if(request.shippedAt().isBefore(((Timestamp)flow.get("domestic_received_at")).toLocalDateTime()))throw bad("交寄时间不能早于国内收货完成");
|
||||
if(request.shippedAt().isBefore(((LocalDateTime)flow.get("domestic_received_at"))))throw bad("交寄时间不能早于国内收货完成");
|
||||
}
|
||||
long id=IdWorker.getId();String number="PS-"+UUID.randomUUID().toString().replace("-","").substring(0,24).toUpperCase();
|
||||
jdbc.update("INSERT INTO ll_procurement_shipment(id,order_id,customer_id,shipment_no,leg,manifest_id,shipped_at,address_snapshot,created_by) VALUES(?,?,?,?,?,?,?,CAST(? AS JSON),?)",
|
||||
|
||||
Reference in New Issue
Block a user