diff --git a/app/build.gradle b/app/build.gradle index 10642fc..ee530b6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,7 +9,7 @@ plugins { // 避免不同尺寸機台間版本號產生衝突。 // ========================================================================= def verMinor = 1 -def verPatch = 24 +def verPatch = 30 android { diff --git a/app/src/Cmuh/java/com/unibuy/smartdevice/ui/SaleFlowHandler.java b/app/src/Cmuh/java/com/unibuy/smartdevice/ui/SaleFlowHandler.java index 636fe6e..218ce96 100644 --- a/app/src/Cmuh/java/com/unibuy/smartdevice/ui/SaleFlowHandler.java +++ b/app/src/Cmuh/java/com/unibuy/smartdevice/ui/SaleFlowHandler.java @@ -47,6 +47,7 @@ import javax.crypto.spec.SecretKeySpec; public class SaleFlowHandler { private static final String ORDC_EMPTY = "ORDC_EMPTY"; private static final String MATERIAL_NOT_FOUND = "MATERIAL_NOT_FOUND"; + private static final String STOCK_EMPTY = "STOCK_EMPTY"; private static final String STOCK_NOT_ENOUGH = "STOCK_NOT_ENOUGH"; protected final Context context; @@ -270,7 +271,13 @@ public class SaleFlowHandler { } int totalStock = 0; for (SlotStructure slotData : matchedSlots) { - totalStock += slotData.getCount(); + if (isAvailableCmuhStock(slotData)) { + totalStock += slotData.getCount(); + } + } + if (totalStock <= 0) { + failWithCode(STOCK_EMPTY, context.getString(R.string.cmuh_stock_empty, ordc)); + return; } if (requestQty <= 0 || totalStock < requestQty) { failWithCode(STOCK_NOT_ENOUGH, context.getString(R.string.cmuh_stock_not_enough, ordc, requestQty, totalStock)); @@ -293,6 +300,7 @@ public class SaleFlowHandler { MemoSnDrgno = ""; List matchedSlots = materialSlotMap.get(ordc); for (SlotStructure matchedSlot : matchedSlots) { + if (!isAvailableCmuhStock(matchedSlot)) continue; MedicineCount += matchedSlot.getCount(); MedicineSlot += matchedSlot.getSlot() + "-" + matchedSlot.getCount() + ","; if (MedicineCount >= requestQty) { @@ -363,12 +371,19 @@ public class SaleFlowHandler { String materialCode = slotData.getProduct().getMaterialCode(); if (productId == null || productId.isEmpty() || "?".equals(productId)) continue; if (materialCode == null || materialCode.trim().isEmpty()) continue; - if (slotData.getCount() <= 0 || slotData.getCount() > 20) continue; + if (slotData.getSlot() <= 0) { + MyApp.getInstance().getLogs().info("Skip invalid VMC slot for CMUH pickup: " + slotData.getSlot()); + continue; + } materialSlotMap.computeIfAbsent(materialCode.trim(), k -> new ArrayList<>()).add(slotData); } return materialSlotMap; } + private boolean isAvailableCmuhStock(SlotStructure slotData) { + return slotData != null && slotData.getCount() > 0 && slotData.getCount() <= 20; + } + private int safeParseInt(String value, int defaultValue) { try { return Integer.parseInt(value); @@ -378,17 +393,21 @@ public class SaleFlowHandler { } private void failWithCode(String code, String message) { - String finalMessage = "@" + code + " " + message; MyApp.getInstance().getLogs().info("[" + code + "] " + message); - MyApp.getInstance().setCmuhPickupErrorMessage(finalMessage.substring(1)); + MyApp.getInstance().setCmuhPickupErrorMessage(message); haveValuestate = false; openBarcode = false; MyApp.getInstance().getBuyList().clear(); } public void addMedicineToBuyList(String MedicinePidStr, String MedicineNameStr, int SlotNumber, String MedicineImg, String MemoSnDrgno, int count) { + if (SlotNumber <= 0) { + failWithCode(MATERIAL_NOT_FOUND, context.getString(R.string.cmuh_material_not_found, MedicinePidStr)); + MyApp.getInstance().getLogs().info("CMUH pickup blocked invalid slot: slot=" + SlotNumber + ", pid=" + MedicinePidStr + ", name=" + MedicineNameStr); + return; + } ProductStructure productStructure = new ProductStructure(MedicinePidStr, MedicineImg, MedicineNameStr, 0, 0, 0, 0, MemoSnDrgno, "", "", ""); - MyApp.getInstance().getLogs().info("aaaaaa " + MedicinePidStr + " " + MemoSnDrgno + " " + MedicineNameStr); + MyApp.getInstance().getLogs().info("CMUH pickup add buy item: slot=" + SlotNumber + ", pid=" + MedicinePidStr + ", name=" + MedicineNameStr); BuyStructure buyProduct = new BuyStructure(0, SlotNumber, productStructure, count); MyApp.getInstance().getBuyList().add(buyProduct); } diff --git a/app/src/Cmuh/java/com/unibuy/smartdevice/ui/recycler/RecyclerDialogPickupCodeBuyListAdpter.java b/app/src/Cmuh/java/com/unibuy/smartdevice/ui/recycler/RecyclerDialogPickupCodeBuyListAdpter.java index fdae52f..67418ae 100644 --- a/app/src/Cmuh/java/com/unibuy/smartdevice/ui/recycler/RecyclerDialogPickupCodeBuyListAdpter.java +++ b/app/src/Cmuh/java/com/unibuy/smartdevice/ui/recycler/RecyclerDialogPickupCodeBuyListAdpter.java @@ -59,7 +59,7 @@ public class RecyclerDialogPickupCodeBuyListAdpter extends RecyclerView.Adapter< logs.info("position:" + position); BuyStructure buyProduct = buyList.get(position); - holder.binding.textPosition.setText(String.valueOf(position)); + holder.binding.textPosition.setText(String.valueOf(position + 1)); String productID = buyProduct.getProduct().getProductID(); if (!productID.isEmpty() && !productID.equals("?")) { holder.binding.textProductName.setText(buyProduct.getProduct().getProductName()); diff --git a/app/src/Cmuh/java/com/unibuy/smartdevice/ui/recycler/RecyclerDialogTakeMedicineListAdpter.java b/app/src/Cmuh/java/com/unibuy/smartdevice/ui/recycler/RecyclerDialogTakeMedicineListAdpter.java index 7a0bf2d..95bc117 100644 --- a/app/src/Cmuh/java/com/unibuy/smartdevice/ui/recycler/RecyclerDialogTakeMedicineListAdpter.java +++ b/app/src/Cmuh/java/com/unibuy/smartdevice/ui/recycler/RecyclerDialogTakeMedicineListAdpter.java @@ -54,7 +54,7 @@ public class RecyclerDialogTakeMedicineListAdpter extends RecyclerView.Adapter buyList = MyApp.getInstance().getBuyList(); if (buyList.size() > 1) { - getLogs().info("⚠️ BuyList 有多筆,只處理第一筆,其餘略過。"); + getLogs().info("✅ BuyList 有多筆,將依序連續出貨。"); } for (BuyStructure buyStructure: buyList) { @@ -297,7 +297,6 @@ public class DispatchDialog extends DialogAbstract { int pcount = buyStructure.getCount(); deliveryLogs.add("▲ 應出貨明細 - " + ptId + " / " + pName + " / 數量 " + pcount); - break; // ✅ 加入這行防呆:只處理一筆後跳出 } getLogs().info("DispatchList size:" + this.dispatchList.size()); diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml index 606c525..dc9c1da 100644 --- a/app/src/main/res/values-en/strings.xml +++ b/app/src/main/res/values-en/strings.xml @@ -394,7 +394,8 @@ This will download all products from the cloud and overwrite any unsaved local inventory changes. Are you sure you want to continue? Downloading product data... Missing ORDC in prescription data. Please scan again or contact pharmacy staff. - Item [%1$s] has no stock or no assigned slot. Please verify configuration. + Item [%1$s] has no assigned slot. Please contact pharmacy staff. + Item [%1$s] is currently out of stock. Please contact pharmacy staff. Item [%1$s] has insufficient stock. Required: %2$d, Available: %3$d MATERIAL_CODE_EMPTY Slot %1$d product %2$s is missing material code. Please fix product master data first. Pickup failed\nPlease contact the counter diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index c67fa0c..833c697 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -396,7 +396,8 @@ 同期中... 商品データの同期が完了しました 処方データに ORDC がありません。再度スキャンするか薬局窓口へお問い合わせください。 - 商品 [%1$s] は在庫切れ、またはスロット未設定です。設定を確認してください。 + 商品 [%1$s] はスロット未設定です。薬局窓口へお問い合わせください。 + 商品 [%1$s] は現在在庫切れです。薬局窓口へお問い合わせください。 商品 [%1$s] の在庫が不足しています。必要数: %2$d、在庫: %3$d MATERIAL_CODE_EMPTY スロット %1$d の商品 %2$s に物料コードがありません。商品マスタを修正してください。 受け取り失敗\nカウンターへお問い合わせください diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3b6894e..a39f230 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -313,7 +313,8 @@ 資料上傳失敗 上傳後台並返回 領藥單缺少 ORDC,請重新掃碼或洽藥局窗口。 - 商品 [%1$s] 無庫存或未設定貨道,請確認。 + 商品 [%1$s] 未設定貨道,請洽藥局窗口。 + 商品 [%1$s] 目前無庫存,請洽藥局窗口。 商品 [%1$s] 庫存不足,需求:%2$d,可用:%3$d MATERIAL_CODE_EMPTY 貨道 %1$d 商品 %2$s 缺少物料編號,請先修正商品主檔。 取物失敗\n請洽櫃台