123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- package thyyxxk.sizyfeeoprnsystm.service;
- import com.alibaba.fastjson.JSONArray;
- import com.alibaba.fastjson.JSONObject;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.web.client.RestTemplate;
- import thyyxxk.sizyfeeoprnsystm.dao.SiLogDao;
- import thyyxxk.sizyfeeoprnsystm.dao.SiZyDao;
- import thyyxxk.sizyfeeoprnsystm.dicts.MdtrtCertType;
- import thyyxxk.sizyfeeoprnsystm.dicts.PsnSetlWay;
- import thyyxxk.sizyfeeoprnsystm.dicts.SiFunction;
- import thyyxxk.sizyfeeoprnsystm.dicts.YesOrNo;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import thyyxxk.sizyfeeoprnsystm.pojo.*;
- import thyyxxk.sizyfeeoprnsystm.utils.*;
- import java.text.SimpleDateFormat;
- import java.util.*;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.atomic.AtomicInteger;
- /**
- * @author dj
- */
- @Slf4j
- @Service
- public class SiZyFeeService {
- private static final String RESULT_CODE = "infcode";
- private static final String ERROR_MESSAGE = "err_msg";
- private static final String OUTPUT = "output";
- private final SiZyDao zyDao;
- private final SiLogDao logDao;
- private final ExecService exec;
- @Value("${upld-notify-url}")
- private String upldNotifyUrl;
- @Autowired
- public SiZyFeeService(SiZyDao zyDao, SiLogDao logDao, ExecService exec) {
- this.zyDao = zyDao;
- this.logDao = logDao;
- this.exec = exec;
- }
- private void revokeUploadFees(ZyPatientInfo p) {
- if (null == p.getDetailSns() || p.getDetailSns().isEmpty()) {
- return;
- }
- SiPatInfo siPatInfo = zyDao.selectSiPatInfoForZy(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn());
- if (null == siPatInfo || StringUtil.isBlank(siPatInfo.getMdtrtId())) {
- return;
- }
- JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.REVOKE_HOSPITALIZATION_FEE_DETAILS,
- siPatInfo.getInsuplcAdmdvs(), p.getStaffId());
- JSONArray data = new JSONArray();
- p.getDetailSns().forEach(detailSn -> {
- JSONObject item = new JSONObject();
- item.put("feedetl_sn", detailSn);
- item.put("mdtrt_id", siPatInfo.getMdtrtId());
- item.put("psn_no", siPatInfo.getPsnNo());
- data.add(item);
- });
- input.getJSONObject("input").put("data", data);
- JSONObject result = exec.executeTrade(input, SiFunction.REVOKE_HOSPITALIZATION_FEE_DETAILS);
- log.info("【操作员:{}】撤销已上传的费用:\n参数:{},\n结果:{}", p.getStaffId(), input, result);
- if (null == result || null == result.getInteger(RESULT_CODE)) {
- ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
- return;
- }
- if (result.getIntValue(RESULT_CODE) == 0) {
- if (null == p.getDetailSns() || p.getDetailSns().isEmpty()) {
- zyDao.revokeAllUploadFee(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn());
- zyDao.deleteSiChrmTemp(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn());
- } else {
- zyDao.revokePartUploadFee(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn(), p.getDetailSns());
- zyDao.deletePartSiChrmTemp(p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn(), p.getDetailSns());
- }
- ResultVoUtil.success("撤销费用上传成功。");
- }
- }
- public ResultVo<String> uploadFeeDetail(Overview o) {
- if (null == o.getLedgerSn()) {
- Integer ledger = zyDao.selectMaxLedgerSn(o.getInpatientNo(), o.getAdmissTimes());
- if (null == ledger) {
- ledger = 1;
- }
- o.setLedgerSn(ledger);
- }
- if (null == o.getMidSetl()) {
- o.setMidSetl(false);
- }
- SiPatInfo siPatInfo = zyDao.selectSiPatInfoForZy(o.getInpatientNo(), o.getAdmissTimes(), o.getLedgerSn());
- if (null == siPatInfo || StringUtil.isBlank(siPatInfo.getMdtrtId())) {
- return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "此患者没有有效的医保在院信息!");
- }
- beforeUpload(o);
- zyDao.hisRecount(o.getInpatientNo(), o.getAdmissTimes(), o.getLedgerSn());
- ZyPatientInfo p = zyDao.selectPatientInfo(o.getInpatientNo());
- p.setSid(o.getSid());
- p.setStaffId(o.getStaffId());
- p.setLedgerSn(o.getLedgerSn());
- p.setMdtrtId(siPatInfo.getMdtrtId());
- p.setPsnNo(siPatInfo.getPsnNo());
- p.setMedType(siPatInfo.getMedType());
- p.setAdmdvs(siPatInfo.getInsuplcAdmdvs());
- Queue<FeeDtle> allPositiveFees, allNegativeFees;
- if (o.getMidSetl()) {
- List<Integer> notAllowedSns = zyDao.selectNotAllowedSnForMidSetl(o.getInpatientNo(), o.getAdmissTimes(),
- o.getLedgerSn(), o.getEndtime());
- if (null != notAllowedSns && notAllowedSns.size() > 0) {
- List<Integer> tempSns = new ArrayList<>();
- for (int sn : notAllowedSns) {
- tempSns.add(sn);
- if (tempSns.size() == 100) {
- p.setDetailSns(tempSns);
- revokeUploadFees(p);
- tempSns.clear();
- }
- }
- if (tempSns.size() > 0) {
- p.setDetailSns(tempSns);
- revokeUploadFees(p);
- }
- }
- allPositiveFees = zyDao.selectNotUploadedPositiveFeesForMidSetl(o.getInpatientNo(), o.getAdmissTimes(),
- o.getLedgerSn(), o.getBegntime(), o.getEndtime());
- allNegativeFees = zyDao.selectNotUploadedNegativeFeesForMidSetl(o.getInpatientNo(), o.getAdmissTimes(),
- o.getLedgerSn(), o.getBegntime(), o.getEndtime());
- } else {
- String today = getTodayEndTime();
- allPositiveFees = zyDao.selectNotUploadedPositiveFees(o.getInpatientNo(), o.getAdmissTimes(),
- o.getLedgerSn(), today);
- allPositiveFees.removeIf(item -> StringUtil.isBlank(item.getMedListCodg()));
- allNegativeFees = zyDao.selectNotUploadedNegativeFees(o.getInpatientNo(), o.getAdmissTimes(),
- o.getLedgerSn(), today);
- }
- if (allPositiveFees.size() == 0 && allNegativeFees.size() == 0) {
- return hospitalizationPreSettlement(p, o);
- }
- int index = 0;
- int feeSize = allPositiveFees.size() + allNegativeFees.size();
- index = prepareUploadFees(allPositiveFees, index, feeSize, p, o.getSid());
- prepareUploadFees(allNegativeFees, index, feeSize, p, o.getSid());
- return hospitalizationPreSettlement(p, o);
- }
- private String getTodayEndTime() {
- SimpleDateFormat smdate = new SimpleDateFormat("yyyy-MM-dd");
- String date = smdate.format(new Date());
- return date + " 23:59:59.999";
- }
- private int prepareUploadFees(Queue<FeeDtle> feeQueue, int index, int feeSize, ZyPatientInfo p, String sid) {
- JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.UPLOAD_HOSPITALIZATION_FEE_DETAILS,
- p.getAdmdvs(), p.getStaffId());
- JSONObject socketMessage = new JSONObject();
- socketMessage.put("name", "updateProgress");
- socketMessage.put("percentage", 0);
- List<FeeDtle> tempList = new ArrayList<>();
- RestTemplate template = new RestTemplate();
- while (feeQueue.size() > 0) {
- FeeDtle feeDtle = feeQueue.poll();
- assert feeDtle != null;
- tempList.add(feeDtle);
- if (tempList.size() == 100) {
- executeUploadFees(input, tempList, p);
- tempList.clear();
- index += 100;
- socketMessage.replace("percentage", makePercentage(index, feeSize));
- template.postForObject(upldNotifyUrl + "/sendById",
- new PureCodeName(sid, socketMessage.toJSONString()), String.class);
- }
- }
- if (tempList.size() > 0) {
- executeUploadFees(input, tempList, p);
- index += tempList.size();
- socketMessage.replace("percentage", makePercentage(index, feeSize));
- template.postForObject(upldNotifyUrl + "/sendById",
- new PureCodeName(sid, socketMessage.toJSONString()), String.class);
- }
- return index;
- }
- private void executeUploadFees(JSONObject input, List<FeeDtle> fees, ZyPatientInfo p) {
- String ref = JSONArray.toJSONString(fees);
- input.getJSONObject("input").put("feedetail", JSONArray.parse(ref));
- JSONObject result = exec.executeTrade(input, SiFunction.UPLOAD_HOSPITALIZATION_FEE_DETAILS);
- log.info("【操作员:{}】,医保费用上传结果:{}", p.getStaffId(), result);
- RestTemplate template = new RestTemplate();
- if (null != result) {
- if (result.getIntValue(RESULT_CODE) == 0) {
- zyDao.updateTransFlag(p.getInpatientNo(), p.getAdmissTimes(), fees);
- JSONArray array = result.getJSONObject(OUTPUT).getJSONArray("result");
- List<SiChargeTemp> tempList = new ArrayList<>();
- for (int i = 0; i < array.size(); i++) {
- JSONObject upldretrn = array.getJSONObject(i);
- SiChargeTemp chrgtemp = JSONObject.parseObject(upldretrn.toJSONString(), SiChargeTemp.class);
- chrgtemp.setPatNo(p.getInpatientNo());
- chrgtemp.setTimes(p.getAdmissTimes());
- chrgtemp.setLedgerSn(p.getLedgerSn());
- tempList.add(chrgtemp);
- }
- zyDao.insertSiChargeTempFeeBatch(tempList);
- } else {
- String message = result.getString(ERROR_MESSAGE);
- JSONObject socketMsg = new JSONObject();
- socketMsg.put("name", "uploadFeeResponse");
- socketMsg.put("patNo", p.getInpatientNo());
- socketMsg.put("times", p.getAdmissTimes());
- socketMsg.put("ledgerSn", p.getLedgerSn());
- socketMsg.put("message", message);
- socketMsg.put("title", String.format("住院号:【%s】,住院次数:【%d】,账页号:【%d】。",
- p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn()));
- template.postForObject(upldNotifyUrl + "/sendById",
- new PureCodeName(p.getSid(), socketMsg.toJSONString()), String.class);
- }
- }
- }
- public ResultVo<String> hospitalizationPreSettlement(ZyPatientInfo p, Overview o) {
- ZyPreSetlmt zyPreSetlmt;
- if (o.getMidSetl()) {
- zyPreSetlmt = zyDao.selectPreSetlmtForMidSetl(p.getInpatientNo(), p.getAdmissTimes(),
- p.getLedgerSn(), o.getBegntime(), o.getEndtime());
- } else {
- zyPreSetlmt = zyDao.selectPreSetlmt(p.getInpatientNo(), p.getAdmissTimes(),
- p.getLedgerSn(), getTodayEndTime());
- }
- if (null == zyPreSetlmt || StringUtil.isBlank(zyPreSetlmt.getMdtrtId())) {
- return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "此患者没有有效的医保在院信息!");
- }
- zyPreSetlmt.setMdtrtCertType(MdtrtCertType.RESIDENT_IDENTITY_CARD.getCode());
- zyPreSetlmt.setPsnSetlway(p.getDbg() ? PsnSetlWay.SETTLE_BY_QUOTA.getCode() : PsnSetlWay.SETTLE_BY_ITEMS.getCode());
- zyPreSetlmt.setAcctUsedFlag(YesOrNo.NO.getCodeStr());
- zyPreSetlmt.setMidSetlFlag(YesOrNo.NO.getCodeStr());
- JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.HOSPITALIZATION_PRE_SETTLEMENT,
- zyPreSetlmt.getInsuplcAdmdvs(), p.getStaffId());
- String ref = JSONObject.toJSONString(zyPreSetlmt);
- input.getJSONObject("input").put("data", JSONObject.parseObject(ref));
- JSONObject result = exec.executeTrade(input, SiFunction.HOSPITALIZATION_PRE_SETTLEMENT);
- log.info("预结算:\n参数:{},\n结果:{}", input, result);
- if (null == result) {
- return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
- }
- Integer infcode = result.getInteger(RESULT_CODE);
- logDao.insert(new SiLog(input, result, p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn(), infcode));
- if (null == infcode) {
- return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错:" + result.getString("message"));
- }
- if (infcode == 0) {
- JSONObject setlinfo = result.getJSONObject(OUTPUT).getJSONObject("setlinfo");
- String fundPay = setlinfo.getString("fund_pay_sumamt");
- zyDao.updateFundPay(fundPay, p.getInpatientNo(), p.getAdmissTimes(), p.getLedgerSn());
- String message = "患者【" + p.getName() + "】院内总费用与医保中心总费用一致,医保报销金额为:¥ " + fundPay + "。";
- return ResultVoUtil.success(message);
- }
- return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
- }
- private int makePercentage(int index, int size) {
- float per = (float)index / (float)size;
- return (int) (per * 100);
- }
- private void beforeUpload(Overview o) {
- Date disdate = zyDao.selectDscgDate(o.getInpatientNo(), o.getAdmissTimes());
- if (null != disdate) {
- int num = zyDao.updateChargedate(o.getInpatientNo(), o.getAdmissTimes(), disdate);
- log.info("修改费用时间大于出院医嘱时间的费用条目数:{}", num);
- }
- List<FeeCounteract> negative = zyDao.selectNegativeFeesWithOriDetlSn(
- o.getInpatientNo(), o.getAdmissTimes(), o.getLedgerSn());
- if (null == negative || negative.isEmpty()) {
- log.info("正负相抵完成,抵消费用总条目:0");
- return;
- }
- List<FeeCounteract> positive = new ArrayList<>();
- List<Integer> tempSn = new ArrayList<>();
- for (FeeCounteract feeCounteract : negative) {
- tempSn.add(feeCounteract.getOriDetailSn());
- if (tempSn.size() == 30) {
- positive.addAll(zyDao.selectPositiveFeesByDetlSn(
- o.getInpatientNo(), o.getAdmissTimes(), o.getLedgerSn(), tempSn));
- tempSn.clear();
- }
- }
- if (tempSn.size() > 0) {
- positive.addAll(zyDao.selectPositiveFeesByDetlSn(
- o.getInpatientNo(), o.getAdmissTimes(), o.getLedgerSn(), tempSn));
- }
- ConcurrentHashMap<Integer, FeeCounteract> posKeyVal = new ConcurrentHashMap<>();
- positive.forEach(itm -> {
- if (!posKeyVal.containsKey(itm.getDetailSn())) {
- posKeyVal.put(itm.getDetailSn(), itm);
- }
- });
- AtomicInteger count = new AtomicInteger();
- negative.forEach(itm -> {
- if (posKeyVal.containsKey(itm.getOriDetailSn())) {
- FeeCounteract pos = posKeyVal.get(itm.getOriDetailSn());
- if (itm.getChargeAmount() + pos.getChargeAmount() == 0d
- && itm.getChargeFee() + pos.getChargeFee() == 0d) {
- zyDao.updateYbTransFlagInPair(o.getInpatientNo(),
- o.getAdmissTimes(), itm.getDetailSn(), itm.getOriDetailSn());
- count.addAndGet(2);
- }
- }
- });
- log.info("正负相抵完成,抵消费用总条目:{}", count.get());
- }
- }
|