Explorar o código

门诊缴费自动收费和退费

hurugang %!s(int64=2) %!d(string=hai) anos
pai
achega
f5a3d0185c

+ 39 - 6
src/main/java/cn/hnthyy/thmz/controller/mz/MzChargeDetailController.java

@@ -28,6 +28,7 @@ import cn.hnthyy.thmz.vo.*;
 import com.auth0.jwt.interfaces.DecodedJWT;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
+import org.json.JSONObject;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.dao.DataIntegrityViolationException;
 import org.springframework.web.bind.annotation.*;
@@ -88,6 +89,10 @@ public class MzChargeDetailController {
     private MzVisitTableService mzVisitTableService;
     @Autowired
     private RationalUseService rationalUseService;
+    @Autowired
+    private WindowsService windowsService;
+    @Autowired
+    private TransactionService transactionService;
 
     /**
      * 查询费用列表
@@ -784,9 +789,37 @@ public class MzChargeDetailController {
             User tokenUser = (User) JsonUtil.jsontoObject(decodedJWT.getSubject(), User.class);
             //如果返回的是0,表示全退,大于0,表示新的收费记录的就诊次数
             String ipAddress = HttpUtil.getIPAddress(httpServletRequest);
-            int times = mzChargeDetailService.refundFee(tokenUser.getUserIdCode(), mzDepositFileVo, ipAddress);
+            Windows windowsDb = windowsService.queryLastWindowsIpAddress(ipAddress);
+            if (windowsDb == null) {
+                resultMap.put("code", -1);
+                resultMap.put("message", "您暂未配置只能POS机的【路由识别码】,请配置完后重试!");
+                return resultMap;
+            }
+            Map<String, Object> map = mzChargeDetailService.refundFee(tokenUser.getUserIdCode(), mzDepositFileVo, ipAddress);
+            if (map == null) {
+                resultMap.put("code", -1);
+                resultMap.put("message", "退费失败,未知异常");
+                return resultMap;
+            }
+            List<MzDepositFile> needRefundList = (List<MzDepositFile>) map.get("needRefundList");
+            if (needRefundList != null && needRefundList.size() > 0 && StringUtils.isNotBlank(windowsDb.getMisPosRouterCode())) {
+                for(MzDepositFile mzDepositFile:needRefundList){
+                    JSONObject jsonObject = transactionService.refund(windowsDb.getMisPosRouterCode(), mzDepositFile.getAmount(), mzDepositFile.getPatientId()+"_"+mzDepositFile.getTimes(), null, mzDepositFile.getChequeType(), mzDepositFile.getParChannel(), mzDepositFile.getPsordnum(), mzDepositFile.getTransDate(), mzDepositFile.getAgtordnum());
+                    if (jsonObject == null) {
+                        resultMap.put("code", -2);
+                        resultMap.put("message", "缴费记录已退,但是患者智能POS退款失败,请去财务工具查询并退款!");
+                        return resultMap;
+                    }
+                    String resCode = (String) jsonObject.get("resCode");
+                    if (!"00".equals(resCode)) {
+                        resultMap.put("code", -2);
+                        resultMap.put("message", "缴费记录已退,但是患者智能POS退款失败,错误信息为:" + jsonObject.get("resMsg") + "请去财务工具查询并退款!");
+                        return resultMap;
+                    }
+                }
+            }
             resultMap.put("code", 0);
-            resultMap.put("times", times);
+            resultMap.put("times", map.get("times"));
             resultMap.put("patientId", mzDepositFileVo.getPatientId());
             resultMap.put("message", "退费操作成功");
             return resultMap;
@@ -1561,7 +1594,7 @@ public class MzChargeDetailController {
     @RequestMapping(value = "/savePrescription", method = {RequestMethod.POST})
     public Map<String, Object> savePrescription(@RequestBody MzPrescriptionVo mzPrescriptionVo, HttpServletRequest httpServletRequest) {
         Map<String, Object> resultMap = new HashMap<>();
-        Clinic clinic=null;
+        Clinic clinic = null;
         try {
             //原方法开始
 //    User tokenUser = TokenUtil.getUser(httpServletRequest);
@@ -1672,9 +1705,9 @@ public class MzChargeDetailController {
             log.error("系统异常,错误信息{}", e);
             log.error(JsonUtil.object2Json(mzPrescriptionVo));
             //保存就诊记录带id 因为跨数据库回滚失败零时方案,不做正常保存
-            if(clinic!=null){
-                Clinic dbClinic=clinicService.queryById(clinic.getId());
-                if(dbClinic==null){
+            if (clinic != null) {
+                Clinic dbClinic = clinicService.queryById(clinic.getId());
+                if (dbClinic == null) {
                     clinicService.saveClinicWithId(clinic);
                 }
             }

+ 0 - 3
src/main/java/cn/hnthyy/thmz/controller/mz/MzyReqrecController.java

@@ -130,9 +130,6 @@ public class MzyReqrecController {
                         resultMap.put("message", "银联刷卡或者聚合支付交易日期为空!");
                         return resultMap;
                     }
-                    if (StringUtils.isBlank(mzyReqrec.getParChannel())) {
-                        mzyReqrec.setParChannel(null);
-                    }
                 }
             }
             MzZdWorkTime mzZdWorkTime = mzZdWorkTimeService.queryMzZdWorkTimeByCode(mzyReqrec.getAmpm());

+ 1 - 1
src/main/java/cn/hnthyy/thmz/service/his/mz/MzChargeDetailService.java

@@ -139,7 +139,7 @@ public interface MzChargeDetailService {
      * @param ipAddress       客户端IP  自助的时候是传自助编码
      * @return
      */
-    int refundFee(String opId, MzDepositFileVo mzDepositFileVo, String ipAddress) throws MzException;
+    Map<String,Object> refundFee(String opId, MzDepositFileVo mzDepositFileVo, String ipAddress) throws MzException;
 
     /**
      * 获取退费后新产生的缴费明细记录

+ 46 - 7
src/main/java/cn/hnthyy/thmz/service/impl/his/mz/MzChargeDetailServiceImpl.java

@@ -3377,7 +3377,7 @@ public class MzChargeDetailServiceImpl implements MzChargeDetailService {
 
     @Override
     @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
-    public int refundFee(String opId, MzDepositFileVo mzDepositFileVo, String ipAddress) throws MzException {
+    public Map<String,Object> refundFee(String opId, MzDepositFileVo mzDepositFileVo, String ipAddress) throws MzException {
         Windows windows = windowsMapper.selectLastWindowsByIpAddress(ipAddress);
         if (windows == null) {
             throw new MzException("当前操作人未设置窗口号,请先设置!");
@@ -3438,8 +3438,9 @@ public class MzChargeDetailServiceImpl implements MzChargeDetailService {
         List<MzDepositFile> fullNewMzDepositFiles = new ArrayList<>();
         int times = 0;
         int oriTimes = mzDepositFileVo.getTimes();
+        List<MzDepositFile> needRefundList =null;
         if (allRefund) {
-            getDeposFiles(opId, mzDepositFileVo, now, 0, 0, totalAmount, fullNewMzDepositFiles, allRefund, null);
+            needRefundList = getDeposFiles(opId, mzDepositFileVo, now, 0, 0, totalAmount, fullNewMzDepositFiles, allRefund, null);
             if (fullNewMzDepositFiles.size() > 0) {
                 //新增收费方式记录  退费的负数冲抵部分
                 mzDepositFileMapper.batchInsertMzDepositFile(fullNewMzDepositFiles);
@@ -3503,7 +3504,7 @@ public class MzChargeDetailServiceImpl implements MzChargeDetailService {
             //退费后新的收款方式
             List<MzDepositFile> newMzDepositFiles = new ArrayList<>();
             //String payWay = Constants.CASH;
-            getDeposFiles(opId, mzDepositFileVo, now, times, serialNo, totalPayable, fullNewMzDepositFiles, allRefund, newMzDepositFiles);
+            needRefundList =getDeposFiles(opId, mzDepositFileVo, now, times, serialNo, totalPayable, fullNewMzDepositFiles, allRefund, newMzDepositFiles);
             //setMzReceiptSerial(opId, mzDepositFileVo.getPatientId(), times, windows, mzChargeDetails.get(0).getResponceType(), feeMap, now, serialNo, mzReceiptSerial, payWay, totalPayable, 1);
             MzPatientMi mzPatientMi = mzPatientMiService.queryByPatientId(mzDepositFileVo.getPatientId());
             Clinic dbClinic = clinicMapper.selectByPatientIdAndTimesAndReceiptNo(mzDepositFileVo.getPatientId(), mzDepositFileVo.getTimes(), mzDepositFileVo.getReceiptNo());
@@ -3550,7 +3551,10 @@ public class MzChargeDetailServiceImpl implements MzChargeDetailService {
         MzYjReq updateMzYjReq = new MzYjReq(mzDepositFileVo.getPatientId(), oriTimes);
         updateMzYjReq.setPayMark(PayMarkEnum.RETURN_PREMIUM.code);
         mzYjReqService.modifyMzYjReq(updateMzYjReq);
-        return times;
+        Map<String,Object> resultMap = new HashMap<>();
+        resultMap.put("times",times);
+        resultMap.put("needRefundList",needRefundList);
+        return resultMap;
     }
 
 
@@ -3662,7 +3666,7 @@ public class MzChargeDetailServiceImpl implements MzChargeDetailService {
      * @param newMzDepositFiles
      * @return
      */
-    private void getDeposFiles(String opId, MzDepositFileVo mzDepositFileVo, Date now, int times, int serialNo, BigDecimal totalPayable, List<MzDepositFile> fullNewMzDepositFiles, boolean allRefund, List<MzDepositFile> newMzDepositFiles) {
+    private List<MzDepositFile> getDeposFiles(String opId, MzDepositFileVo mzDepositFileVo, Date now, int times, int serialNo, BigDecimal totalPayable, List<MzDepositFile> fullNewMzDepositFiles, boolean allRefund, List<MzDepositFile> newMzDepositFiles) {
         List<MzDepositFile> mzDepositFiles = mzDepositFileMapper.selectMzDepositFileByTimes(mzDepositFileVo.getPatientId(), mzDepositFileVo.getTimes(), mzDepositFileVo.getReceiptNo(), "mz_deposit_file");
         //本院记账重收的时候。新的收费方式与老的部分收费方式的receiptNo 不一致,所以加这个逻辑
         BigDecimal tempAmount = mzDepositFileMapper.selectSumAmount(mzDepositFileVo.getPatientId(), mzDepositFileVo.getTimes(), mzDepositFileVo.getReceiptNo());
@@ -3670,7 +3674,7 @@ public class MzChargeDetailServiceImpl implements MzChargeDetailService {
             mzDepositFiles = mzDepositFileMapper.selectMzDepositFileByTimesWithOutByjz(mzDepositFileVo.getPatientId(), mzDepositFileVo.getTimes());
         }
         if (mzDepositFiles == null || mzDepositFiles.size() == 0) {
-            return;
+            return null;
         }
         //本院记账总额
         BigDecimal byjzAmount = BigDecimal.ZERO;
@@ -3683,6 +3687,8 @@ public class MzChargeDetailServiceImpl implements MzChargeDetailService {
         //非本院记账总额
         BigDecimal notByjzAmount = BigDecimal.ZERO;
         MzDepositFile temp = null;
+        //需要调用银行接口退费的集合
+        List<MzDepositFile> needRefundList = new ArrayList<>();
         for (MzDepositFile ms : mzDepositFiles) {
             if (ms == null) {
                 continue;
@@ -3695,6 +3701,20 @@ public class MzChargeDetailServiceImpl implements MzChargeDetailService {
                 pGrzhAmount = pGrzhAmount.add(ms.getAmount());
             } else if (Constants.SSHIYBGZ.equals(ms.getChequeType())) {
                 tGrzhAmount = tGrzhAmount.add(ms.getAmount());
+            } else if (Constants.YLK.equals(ms.getChequeType()) || Constants.JHZF.equals(ms.getChequeType())){
+                needRefundList.add(ms);
+                //直接创建负数的
+                MzDepositFile refundMzDepositFile=CloneUtil.clone(ms);
+                refundMzDepositFile.setReceiptNo(-refundMzDepositFile.getReceiptNo());
+                refundMzDepositFile.setAmount(BigDecimal.ZERO.subtract(refundMzDepositFile.getAmount()));
+                refundMzDepositFile.setReceiptSn(-refundMzDepositFile.getReceiptSn());
+                refundMzDepositFile.setSerialNo(-refundMzDepositFile.getSerialNo());
+                refundMzDepositFile.setDeptNo(null);
+                refundMzDepositFile.setChargeDate(now);
+                refundMzDepositFile.setPayMark(PayMarkEnum.RETURN_PREMIUM.code);
+                refundMzDepositFile.setOpId(opId);
+                refundMzDepositFile.setDcountNo(YesNoEnum.NO.code);
+                fullNewMzDepositFiles.add(refundMzDepositFile);
             } else {
                 notByjzAmount = notByjzAmount.add(ms.getAmount());
             }
@@ -3725,6 +3745,8 @@ public class MzChargeDetailServiceImpl implements MzChargeDetailService {
             temp.setPsordnum(null);
             temp.setAgtordnum(null);
             temp.setHisrefundnum(null);
+            temp.setParChannel(null);
+            temp.setTransDate(null);
             //  fullNewMzDepositFiles.add(temp);
         }
         //如果有本院记账的退款金额,本院记账记录保持入库
@@ -3803,7 +3825,7 @@ public class MzChargeDetailServiceImpl implements MzChargeDetailService {
                 // payWay = Constants.BYJZ;
             }
         }
-        // return payWay;
+         return needRefundList;
     }
 
     /**
@@ -4219,6 +4241,23 @@ public class MzChargeDetailServiceImpl implements MzChargeDetailService {
                 }
                 m.setResponceType(null);
             }
+            if(StringUtils.isBlank(m.getChequeType())){
+                throw new MzException("付款方式为空!");
+            }
+            if (Constants.JHZF.equals(m.getChequeType()) || Constants.YLK.equals(m.getChequeType())) {
+                if (StringUtils.isBlank(m.getPsordnum())) {
+                    throw new MzException("银联刷卡或者聚合支付流水号为空");
+                }
+                if (StringUtils.isBlank(m.getParChannel())) {
+                    throw new MzException("银联刷卡或者聚合支付回传支付渠道为空");
+                }
+                if (Constants.JHZF.equals(m.getChequeType()) && StringUtils.isBlank(m.getAgtordnum())) {
+                    throw new MzException("银联刷卡或者聚合支付条形码流水号为空");
+                }
+                if (StringUtils.isBlank(m.getTransDate())) {
+                    throw new MzException("银联刷卡或者聚合支付交易日期为空");
+                }
+            }
             if (m.getPatientId() == null) {
                 //此时是直接收费,需要设置相关参数
                 m.setPatientId(mzDepositFileVo.getPatientId());

+ 1 - 0
src/main/java/cn/hnthyy/thmz/service/impl/thmz/TransactionServiceImpl.java

@@ -156,6 +156,7 @@ public class TransactionServiceImpl implements TransactionService {
             if (StringUtils.isBlank(result)) {
                 return null;
             }
+            log.info(result);
             return new JSONObject(result);
         } catch (Exception e) {
             log.info("调用智能POS{}接口,路由识别码={}", type, routerCode);

+ 65 - 4
src/main/resources/static/js/mz/toll_administration.js

@@ -73,6 +73,12 @@ $(function () {
         }
     });
 
+    /**
+     * 刷卡/扫码
+     */
+    $("#consume").on("click", function (t) {
+        consume();
+    });
 });
 
 /**
@@ -937,6 +943,11 @@ function confirmFeeModal(times, totalCharge, receiptNo) {
     }
     $("#changeAmount").val(0.0);
     $("#surplusAmount").val(0.0);
+
+    $("input.refNo").val(null);
+    $("input.transDate").val(null);
+    $("input.payChannel").val(null);
+    $("input.qrCodeParam").val(null);
     sendPriceMessage(realMoney, 0, 0, $("#patientIdHaveTally").val());
 }
 
@@ -1059,7 +1070,7 @@ function checkFee(flag) {
         //现金收款总额
         var cashAmount = 0;
         for (var i = 0; i < arr.length; i++) {
-            var temp = parseFloat($(arr[i]).find("input").val());
+            var temp = parseFloat($(arr[i]).find("input.money").val());
             if (isNaN(temp)) {
                 temp = 0;
             }
@@ -1349,12 +1360,16 @@ function saveConfirmFee() {
     var arr = $("#payForm").find("div.pay-item");
     if (arr.length > 0) {
         for (var i = 0; i < arr.length; i++) {
-            var temp = parseFloat($(arr[i]).find("input").val());
+            var temp = parseFloat($(arr[i]).find("input.money").val());
             if (temp == null || temp == 0) {
                 continue;
             }
-            var tempJson = JSON.parse('{"chequeType":"","amount":"","contractId":""}');
+            var tempJson = JSON.parse('{"chequeType":"","amount":"","contractId":"","psordnum":"","agtordnum":"","parChannel":"","transDate":""}');
             tempJson.chequeType = $(arr[i]).find("select").val();
+            tempJson.psordnum = $(arr[i]).find("input.refNo").val();
+            tempJson.agtordnum = $(arr[i]).find("input.qrCodeParam").val();
+            tempJson.parChannel = $(arr[i]).find("input.payChannel").val();
+            tempJson.transDate = $(arr[i]).find("input.transDate").val();
             //现金有可能会多收,比入实收37,对方给了100,需要找零63. 所以必须减去找零金额,才是实收金额
             if (tempJson.chequeType == "1") {
                 temp = temp - $("#changeAmount").val();
@@ -2435,7 +2450,7 @@ function addPayType(id) {
         var payTypeIndex = $("#payTypeIndex").val();
         payTypeId = "payType_" + payTypeIndex;
     }
-    var html = '<div class="item form-group pay-item"><div class="col-md-12 col-sm-12 col-xs-12"><div class="col-md-2 col-sm-2 col-xs-12"></div><label class="col-md-3 col-sm-3 col-xs-12"><select class="form-control selectpicker show-tick" required="true" id="' + payTypeId + '" onchange="checkFee(false)"></select></label><div class="col-md-3 col-sm-3 col-xs-12"><input class="form-control col-md-5 col-xs-12" type="number" data-placement="bottom-right" min="0" onchange="checkFee()"></div><div class="col-md-1 col-sm-1 col-xs-12" style="line-height: 34px;">元&nbsp;&nbsp;<a style="line-height: 34px;cursor: pointer;" onclick="closeThisParent(this)"><i class="fa fa-close"></i></a></div></div></div>';
+    var html = '<div class="item form-group pay-item"><div class="col-md-12 col-sm-12 col-xs-12"> <input type="hidden" class="refNo"/><input type="hidden" class="qrCodeParam"/><input type="hidden" class="transDate"/><input type="hidden" class="payChannel"/><div class="col-md-2 col-sm-2 col-xs-12"></div><label class="col-md-3 col-sm-3 col-xs-12"><select class="form-control selectpicker show-tick" required="true" id="' + payTypeId + '" onchange="checkFee(false)"></select></label><div class="col-md-3 col-sm-3 col-xs-12"><input class="form-control col-md-5 col-xs-12 money" type="number" data-placement="bottom-right" min="0" onchange="checkFee()"></div><div class="col-md-1 col-sm-1 col-xs-12" style="line-height: 34px;">元&nbsp;&nbsp;<a style="line-height: 34px;cursor: pointer;" onclick="closeThisParent(this)"><i class="fa fa-close"></i></a></div></div></div>';
     $("#changeAmountParent").before(html);
     initChequeType(payTypeId)
     if (payTypeIndex != undefined && payTypeIndex != null) {
@@ -2911,4 +2926,50 @@ function clearMztcbl() {
     $("#mzblPatientId").val(null);
     $("#mzblTimes").val(null);
     $("#mzblReceiptNo").val(null);
+}
+
+
+
+
+
+/**
+ * 刷卡/扫码
+ */
+function consume() {
+    $("#saveConfirmFee").attr("disabled", true);
+    var current = $("#payForm").find("div.pay-item").last();
+    var patientId = $("#patientIdHaveTally").val();
+    var times = $("#timesHaveTally").val();
+    var chequeType = $(current).find("select").val();
+    var amt = parseFloat($(current).find("input.money").val());
+    $.ajax({
+        type: "POST",
+        url: '/thmz/consume',
+        contentType: "application/json;charset=UTF-8",
+        dataType: "json",
+        data: JSON.stringify({
+            "patientId": patientId,
+            "times": times,
+            "chequeType": chequeType,
+            "amt": amt,
+            "type": 0
+        }),
+        headers: {'Accept': 'application/json', 'Authorization': 'Bearer ' + localStorage.getItem("token")},
+        success: function (res) {
+            if (res == '401' || res == 401) {
+                window.location.href = '/thmz/login/view'
+                return;
+            }
+            if (res.code == 0) {
+                successMesage(res);
+                $(current).find("input.refNo").val(res.data.refNo);
+                $(current).find("input.transDate").val(res.data.transDate);
+                $(current).find("input.payChannel").val(res.data.payChannel);
+                $(current).find("input.qrCodeParam").val(res.data.wxAliPayOrderNo);
+            } else {
+                errorMesage(res);
+            }
+            $("#saveConfirmFee").attr("disabled", false);
+        }
+    });
 }

+ 10 - 1
src/main/resources/templates/mz/toll_administration.html

@@ -171,13 +171,21 @@
                     </div>
                     <div class="item form-group pay-item">
                         <div class="col-md-12 col-sm-12 col-xs-12">
+                            <!--POS主机参考号-->
+                            <input type="hidden" class="refNo"/>
+                            <!--POS条形码编码-->
+                            <input type="hidden" class="qrCodeParam"/>
+                            <!-- POS交易日期-->
+                            <input type="hidden" class="transDate"/>
+                            <!-- POS 支付渠道(CHANNEL_ALIPAY  支付宝,CHANNEL_WEPAY  微信,CHANNEL_DRAGONPAY  龙支付,CHANNEL_UNIONCODEPAY  银联二维码,CHANNEL_UNIONPAY  其他银行卡交易)-->
+                            <input type="hidden" class="payChannel"/>
                             <div class="col-md-2 col-sm-2 col-xs-12"></div>
                             <label class="col-md-3 col-sm-3 col-xs-12" for="cash">
                                 <select class="form-control selectpicker show-tick" required="true"
                                         id="payType" onchange="checkFee(false)"></select>
                             </label>
                             <div class="col-md-3 col-sm-3 col-xs-12">
-                                <input id="cash" class="form-control col-md-5 col-xs-12" type="number"
+                                <input id="cash" class="form-control col-md-5 col-xs-12 money" type="number"
                                        data-placement="bottom-right" min="0" onchange="checkFee(false)">
                             </div>
                             <div class="col-md-1 col-sm-1 col-xs-12" style="line-height: 34px;">元</div>
@@ -232,6 +240,7 @@
                 <!--<input type="checkbox"/>&nbsp;&nbsp;打印-->
                 <!--</div>-->
                 <!--<input type="hidden" id="benYuanJiZhangTimes"/>-->
+                <button type="button" class="btn btn-primary" id="consume">刷卡/扫码</button>
                 <button type="button" class="btn btn-primary" onclick="saveConfirmFee()" id="saveConfirmFee">确定</button>
                <!-- <button type="button" class="btn btn-default" data-dismiss="modal" onclick="cancelFee()">取消</button>-->
                 <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>