[FIX] 修正中國醫 (CMUH) 領藥異常處理與銷貨流水號關聯

1. build.gradle: 升級修補版號 verPatch 31 -> 33。
2. TransactionFinalizeBuilder.java: 新增 orderNo 欄位並提供 setter。預設 orderNo 同 flowId,若呼叫 setOrderNo 則於組建 OrderPayload 時覆寫 order_no。
3. DispatchDialog.java (CMUH):
   - 中國醫 (Cmuh) 取物單 SN 序號改為覆寫 order_no,不再覆寫 flow_id、OrderId 與 ReportFlowId,避免機台底層流程因 ID 重複而拋錯。
   - 修正領藥失敗的 Memo 寫入邏輯:機台未回應重試逾時,移除 insertDrgnoToMemo()。
   - 整單出貨失敗結案時,檢查是否有任何出貨成功紀錄(新增 hasAnySuccessfulDispatch()),僅在有成功出貨時才寫入 Memo,整單未出貨時不寫入,允許使用者重新掃碼領藥。
This commit is contained in:
sky121113 2026-05-29 13:56:21 +08:00
parent b2b6776665
commit 4c9fb5e000
3 changed files with 29 additions and 8 deletions

View File

@ -9,7 +9,7 @@ plugins {
//
// =========================================================================
def verMinor = 1
def verPatch = 31
def verPatch = 33
android {

View File

@ -39,6 +39,9 @@ public class TransactionFinalizeBuilder {
/** 機台本地流水號格式YYYYMMDDXXXX例如 202605110001 */
private String flowId;
/** 銷貨紀錄訂單號,預設同 flow_id特殊流程可覆寫 */
private String orderNo;
/** 累積的出貨結果清單 */
private final List<TransactionFinalizePayload.DispenseRecord> dispenseRecords = new ArrayList<>();
@ -48,6 +51,7 @@ public class TransactionFinalizeBuilder {
this.orderMachineTime = SDF.format(new Date());
// 在進入出貨流程時立即生成本次交易流水號一次交易只生成一次
this.flowId = FlowIdGenerator.next(MyApp.getInstance());
this.orderNo = this.flowId;
Log.i(TAG, "TransactionFinalizeBuilder created, flow_id=" + this.flowId);
}
@ -55,6 +59,10 @@ public class TransactionFinalizeBuilder {
this.flowId = flowId;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public void setCodeId(String codeId) {
this.codeId = codeId;
}
@ -126,6 +134,7 @@ public class TransactionFinalizeBuilder {
payload.setDispense(new ArrayList<>(dispenseRecords));
Log.i(TAG, "TransactionFinalizePayload built: flow_id=" + flowId
+ ", order_no=" + order.getOrder_no()
+ ", items=" + order.getItems().size()
+ ", dispense=" + dispenseRecords.size());
@ -159,7 +168,7 @@ public class TransactionFinalizeBuilder {
private TransactionFinalizePayload.OrderPayload buildOrderPayload(ReportFlowInfoStructure flowInfo) {
TransactionFinalizePayload.OrderPayload order = new TransactionFinalizePayload.OrderPayload();
order.setOrder_no(flowId);
order.setOrder_no(orderNo != null && !orderNo.isEmpty() ? orderNo : flowId);
// 金額資訊
int totalAmount = flowInfo.getTotalPrice();

View File

@ -340,12 +340,11 @@ public class DispatchDialog extends DialogAbstract {
// 設定到 flowBarCode (會連動到後台 member_barcode 欄位)
MyApp.getInstance().getReportFlowInfoData().setFlowBarCode(barcodeInfo);
// 序號是 flow_id將交易流水號與本地 OrderId / ReportFlowId 覆寫為純藥單序號 SN
// CMUH: flow_id 保留 App 機台流水號order_no 使用取物單序號 SN 方便後台對藥單
if (sn != null && !sn.isEmpty()) {
finalizeBuilder.setFlowId(sn);
finalizeBuilder.setOrderNo(sn);
MyApp.getInstance().getReportFlowInfoData().setOrderId(sn);
MyApp.getInstance().getReportFlowInfoData().setReportFlowId(sn);
getLogs().info("✅ 交易流水號已成功覆寫為純藥單序號 (SN)" + sn);
getLogs().info("✅ 中國醫銷貨紀錄 order_no 已設定為取物單序號 (SN)" + sn);
}
} catch (Exception e) {
getLogs().warning(e);
@ -514,7 +513,6 @@ public class DispatchDialog extends DialogAbstract {
buttonControlCountdown.shutdown();
if (isCmuh) {
getLogs().info("機台未回應,已達 Cmuh 最大重試次數 10 次,嘗試重新連線下位機");
insertDrgnoToMemo(); // 領藥失敗新增醫令至 Memo 防止雙重領取
MyApp.getInstance().getDevXinYuanController().start();
if (!MyApp.checkAndReconnectDev()) {
getLogs().info("無法連線到下位機,出貨作業中止");
@ -969,8 +967,10 @@ public class DispatchDialog extends DialogAbstract {
addFailedDispenseRecordsFromCurrent();
if ("Cmuh".equalsIgnoreCase(com.unibuy.smartdevice.BuildConfig.FLAVOR_project)) {
if ("Cmuh".equalsIgnoreCase(com.unibuy.smartdevice.BuildConfig.FLAVOR_project) && hasAnySuccessfulDispatch()) {
insertDrgnoToMemo();
} else if ("Cmuh".equalsIgnoreCase(com.unibuy.smartdevice.BuildConfig.FLAVOR_project)) {
getLogs().info("CMUH 整單未出貨成功,不寫入 SN/DRGNO Memo允許重新掃碼領藥");
}
getLogs().info("出貨失敗,發送 MQTT Finalize 結案訊息: " + message);
@ -1015,6 +1015,18 @@ public class DispatchDialog extends DialogAbstract {
}
}
private boolean hasAnySuccessfulDispatch() {
if (dispatchList == null || dispatchList.isEmpty()) {
return false;
}
for (DispatchStructure dispatch : dispatchList) {
if (dispatch.getCount() > 0) {
return true;
}
}
return false;
}
private void deliverylot(int msgflag){
String productId = dispatchList.get(dispatchIndex).getProduct().getProductID();