diff --git a/bms-back/bms-system/src/main/java/com/bms/price/enums/BillBillingFailStatus.java b/bms-back/bms-system/src/main/java/com/bms/price/enums/BillBillingFailStatus.java index cb51d10e..aa37f110 100644 --- a/bms-back/bms-system/src/main/java/com/bms/price/enums/BillBillingFailStatus.java +++ b/bms-back/bms-system/src/main/java/com/bms/price/enums/BillBillingFailStatus.java @@ -43,4 +43,29 @@ public enum BillBillingFailStatus { return code != null && code.intValue() > SUCCESS.code; } + + /** + * Map soft-fail status to prc_billing_task.fail_code. + */ + public static String toTaskFailCode(Integer billingFailStatus) + { + BillBillingFailStatus status = of(billingFailStatus); + if (status == null || status == SUCCESS) + { + return null; + } + if (status == PRODUCT) + { + return BillTaskFailCode.PRODUCT_NOT_HIT.getCode(); + } + if (status == COUNTRY) + { + return BillTaskFailCode.COUNTRY_NOT_HIT.getCode(); + } + if (status == WEIGHT) + { + return BillTaskFailCode.WEIGHT_NOT_HIT.getCode(); + } + return BillTaskFailCode.UNKNOWN.getCode(); + } } diff --git a/bms-back/bms-system/src/main/java/com/bms/price/enums/BillTaskFailCode.java b/bms-back/bms-system/src/main/java/com/bms/price/enums/BillTaskFailCode.java index 42ab88c6..a170ec7e 100644 --- a/bms-back/bms-system/src/main/java/com/bms/price/enums/BillTaskFailCode.java +++ b/bms-back/bms-system/src/main/java/com/bms/price/enums/BillTaskFailCode.java @@ -12,6 +12,12 @@ public enum BillTaskFailCode NO_ACTIVE_PACKAGE_VERSION("NO_ACTIVE_PACKAGE_VERSION"), ALREADY_IN_AR_BILL("ALREADY_IN_AR_BILL"), PRODUCT_ARCHIVE_MISSING("PRODUCT_ARCHIVE_MISSING"), + /** Soft-fail: product not in package (incl. after product_code_mapping). */ + PRODUCT_NOT_HIT("PRODUCT_NOT_HIT"), + /** Soft-fail: product hit but country/zone miss. */ + COUNTRY_NOT_HIT("COUNTRY_NOT_HIT"), + /** Soft-fail: product+country hit but weight band miss. */ + WEIGHT_NOT_HIT("WEIGHT_NOT_HIT"), PRICE_NOT_HIT("PRICE_NOT_HIT"), ZONE_PRICE_NOT_HIT("ZONE_PRICE_NOT_HIT"), POSTCODE_REQUIRED("POSTCODE_REQUIRED"), @@ -66,11 +72,25 @@ public enum BillTaskFailCode { return PRODUCT_ARCHIVE_MISSING.code; } + // Soft-fail messages from price.bill.billingFail.* (order matters: weight/country before generic) + if (containsAny(msg, "\u672a\u5339\u914d\u91cd\u91cf\u6bb5", "WEIGHT_NOT_HIT", "billingFail.weight")) + { + return WEIGHT_NOT_HIT.code; + } + if (containsAny(msg, "\u672a\u5339\u914d\u56fd\u5bb6", "COUNTRY_NOT_HIT", "billingFail.country")) + { + return COUNTRY_NOT_HIT.code; + } + if (containsAny(msg, "\u672a\u5339\u914d\u4ea7\u54c1", "PRODUCT_NOT_HIT", "billingFail.product", "productNotInPackage")) + { + return PRODUCT_NOT_HIT.code; + } if (containsAny(msg, "\u8be5\u5206\u533a\u65e0\u5bf9\u5e94\u4ea7\u54c1\u91cd\u91cf\u6bb5", "zonePriceNotHit", "ZONE_PRICE_NOT_HIT")) { return ZONE_PRICE_NOT_HIT.code; } - if (containsAny(msg, "\u6ca1\u6709\u4ea7\u54c1/\u56fd\u5bb6/\u91cd\u91cf\u6bb5", "priceNotHit", "PRICE_NOT_HIT")) + if (containsAny(msg, "\u6ca1\u6709\u4ea7\u54c1/\u56fd\u5bb6/\u91cd\u91cf\u6bb5", "priceNotHit", "PRICE_NOT_HIT", + "packagePriceNotHit", "packageZonePriceNotHit")) { return PRICE_NOT_HIT.code; } diff --git a/bms-back/bms-system/src/main/java/com/bms/price/service/impl/PrcBillingTaskServiceImpl.java b/bms-back/bms-system/src/main/java/com/bms/price/service/impl/PrcBillingTaskServiceImpl.java index 8b4dc46c..ea70b795 100644 --- a/bms-back/bms-system/src/main/java/com/bms/price/service/impl/PrcBillingTaskServiceImpl.java +++ b/bms-back/bms-system/src/main/java/com/bms/price/service/impl/PrcBillingTaskServiceImpl.java @@ -20,6 +20,7 @@ import com.bms.price.domain.vo.BillingTaskRetryByFilterRequest; import com.bms.price.domain.vo.BillingTaskSubmitRequest; import com.bms.price.domain.vo.TmsPriceBillRequest; import com.bms.price.domain.vo.TmsPriceQuoteResult; +import com.bms.price.enums.BillBillingFailStatus; import com.bms.price.enums.BillTaskFailCode; import com.bms.price.enums.BillTaskSuccessStatus; import com.bms.price.enums.BillTaskType; @@ -187,7 +188,7 @@ public class PrcBillingTaskServiceImpl implements IPrcBillingTaskService fillCustomerCodeFromBill(task, refundOrderNo); TmsPriceQuoteResult result = refundWithDbRetry(taskId, refundOrderNo); writeback(task, BillTaskSuccessStatus.SUCCESS, result == null ? null : result.getBillId(), - null); + null, null); return; } @@ -233,13 +234,26 @@ public class PrcBillingTaskServiceImpl implements IPrcBillingTaskService task.setCustomerCode(billReq.getCustomerCode()); TmsPriceQuoteResult result = billWithDbRetry(taskId, billReq); - writeback(task, BillTaskSuccessStatus.SUCCESS, result == null ? null : result.getBillId(), - null); + // Soft-fail (product/country/weight miss): order bill already persisted with zero amounts; + // still mark task FAILED so it appears in abnormal-task list for retry/ops. + if (result != null && BillBillingFailStatus.isFail(result.getBillingFailStatus())) + { + String err = StringUtils.isNotEmpty(result.getMatchMessage()) + ? result.getMatchMessage() + : ("billingFailStatus=" + result.getBillingFailStatus()); + writeback(task, BillTaskSuccessStatus.FAILED, result.getBillId(), cut(err, 900), + BillBillingFailStatus.toTaskFailCode(result.getBillingFailStatus())); + } + else + { + writeback(task, BillTaskSuccessStatus.SUCCESS, result == null ? null : result.getBillId(), + null, null); + } } catch (RuntimeException e) { log.error("billing task failed taskId={}", taskId, e); - writeback(task, BillTaskSuccessStatus.FAILED, null, cut(e.getMessage(), 900)); + writeback(task, BillTaskSuccessStatus.FAILED, null, cut(e.getMessage(), 900), null); } } @@ -504,7 +518,7 @@ public class PrcBillingTaskServiceImpl implements IPrcBillingTaskService } private void writeback(PrcBillingTask task, BillTaskSuccessStatus status, String billId, - String errorMessage) + String errorMessage, String failCode) { PrcBillingTask upd = new PrcBillingTask(); upd.setTaskId(task.getTaskId()); @@ -516,7 +530,8 @@ public class PrcBillingTaskServiceImpl implements IPrcBillingTaskService } if (BillTaskSuccessStatus.FAILED == status) { - upd.setFailCode(BillTaskFailCode.resolveCode(errorMessage)); + upd.setFailCode(StringUtils.isNotEmpty(failCode) + ? failCode : BillTaskFailCode.resolveCode(errorMessage)); } else { diff --git a/bms-front/src/views/monitor/billingTask/components/billingTaskOptions.js b/bms-front/src/views/monitor/billingTask/components/billingTaskOptions.js index 4884f27e..2e3314bf 100644 --- a/bms-front/src/views/monitor/billingTask/components/billingTaskOptions.js +++ b/bms-front/src/views/monitor/billingTask/components/billingTaskOptions.js @@ -17,6 +17,9 @@ export const failCodeOptions = [ { label: 'NO_ACTIVE_PACKAGE_VERSION', value: 'NO_ACTIVE_PACKAGE_VERSION' }, { label: 'ALREADY_IN_AR_BILL', value: 'ALREADY_IN_AR_BILL' }, { label: 'PRODUCT_ARCHIVE_MISSING', value: 'PRODUCT_ARCHIVE_MISSING' }, + { label: 'PRODUCT_NOT_HIT', value: 'PRODUCT_NOT_HIT' }, + { label: 'COUNTRY_NOT_HIT', value: 'COUNTRY_NOT_HIT' }, + { label: 'WEIGHT_NOT_HIT', value: 'WEIGHT_NOT_HIT' }, { label: 'PRICE_NOT_HIT', value: 'PRICE_NOT_HIT' }, { label: 'ZONE_PRICE_NOT_HIT', value: 'ZONE_PRICE_NOT_HIT' }, { label: 'POSTCODE_REQUIRED', value: 'POSTCODE_REQUIRED' },