Index: ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/foreigntousseapplication/service/ForeignTousseApplicationManagerImpl.java =================================================================== diff -u -r35682 -r35795 --- ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/foreigntousseapplication/service/ForeignTousseApplicationManagerImpl.java (.../ForeignTousseApplicationManagerImpl.java) (revision 35682) +++ ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/foreigntousseapplication/service/ForeignTousseApplicationManagerImpl.java (.../ForeignTousseApplicationManagerImpl.java) (revision 35795) @@ -435,14 +435,19 @@ .getOrgUnitSequence(application.getDepartCoding())); application.setRecyclingStatus(InvoicePlan.RECYCLINGSTATUS_AWAITRECEIVE); application.setDeliverStatus(InvoicePlan.DELIVERSTATUS_AWAITDELIVER); - application.setCommittedStatus(true); + if(application.getCommittedStatus() == null){ + application.setCommittedStatus(true); + } application.setIncludeRecyclingItems(InvoicePlan.SIGNED_TRUE); } if(StringUtils.isBlank(foreignTousseTreeData)){ throw new RuntimeException("外来器械申请单无物品申请!"); } application.setSubmitTime(new Date()); + if(DatabaseUtil.isPoIdValid(application.getId())){ + application.setCommittedStatus(true); + } saveOrUpdate(application); JSONArray jsonArray = JSONArray.fromObject(foreignTousseTreeData); Index: ssts-webservice/src/main/java/com/forgon/disinfectsystem/webservice/datasync/qysrmyy/HIPMessageWebService.java =================================================================== diff -u --- ssts-webservice/src/main/java/com/forgon/disinfectsystem/webservice/datasync/qysrmyy/HIPMessageWebService.java (revision 0) +++ ssts-webservice/src/main/java/com/forgon/disinfectsystem/webservice/datasync/qysrmyy/HIPMessageWebService.java (revision 35795) @@ -0,0 +1,16 @@ +package com.forgon.disinfectsystem.webservice.datasync.qysrmyy; + +import javax.jws.WebMethod; +import javax.jws.WebParam; +import javax.jws.WebService; + +/** + * QYSRMYY-53 接收his推送的外来器械申请单信息(基于web service) + */ +@WebService(serviceName="HIPMessageWebService") +public interface HIPMessageWebService { + + @WebMethod(operationName="HIPMessageServer") + public String HIPMessageServer(@WebParam(name="action") String action, @WebParam(name="message") String message); + +} Index: ssts-webservice/src/main/java/com/forgon/disinfectsystem/webservice/datasync/qysrmyy/HIPMessageWebServiceImpl.java =================================================================== diff -u --- ssts-webservice/src/main/java/com/forgon/disinfectsystem/webservice/datasync/qysrmyy/HIPMessageWebServiceImpl.java (revision 0) +++ ssts-webservice/src/main/java/com/forgon/disinfectsystem/webservice/datasync/qysrmyy/HIPMessageWebServiceImpl.java (revision 35795) @@ -0,0 +1,436 @@ +package com.forgon.disinfectsystem.webservice.datasync.qysrmyy; + +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import jxl.common.Logger; +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringEscapeUtils; +import org.apache.commons.lang.StringUtils; +import org.dom4j.Document; +import org.dom4j.DocumentHelper; +import org.dom4j.Node; +import org.dom4j.XPath; +import org.springframework.beans.factory.annotation.Autowired; + +import com.forgon.Constants; +import com.forgon.directory.acegi.tools.AcegiHelper; +import com.forgon.directory.model.OrgUnit; +import com.forgon.directory.service.OrgUnitManager; +import com.forgon.disinfectsystem.basedatamanager.supplier.service.SupplierManager; +import com.forgon.disinfectsystem.basedatamanager.supplyroomconfig.service.SupplyRoomConfigManager; +import com.forgon.disinfectsystem.entity.basedatamanager.materialdefinition.MaterialDefinition; +import com.forgon.disinfectsystem.entity.basedatamanager.materialinstance.MaterialInstance; +import com.forgon.disinfectsystem.entity.basedatamanager.supplier.Supplier; +import com.forgon.disinfectsystem.entity.basedatamanager.supplyroomconfig.SupplyRoomConfig; +import com.forgon.disinfectsystem.entity.basedatamanager.toussedefinition.TousseDefinition; +import com.forgon.disinfectsystem.entity.foreigntousseapplication.ForeignTousseApplication; +import com.forgon.disinfectsystem.entity.invoicemanager.InvoicePlan; +import com.forgon.disinfectsystem.foreigntousseapplication.service.ForeignTousseApplicationManager; +import com.forgon.exception.SystemException; +import com.forgon.log.model.Log; +import com.forgon.log.service.LogManager; +import com.forgon.tools.GB2Alpha; +import com.forgon.tools.GB2WB; +import com.forgon.tools.date.DateTools; +import com.forgon.tools.db.DatabaseUtil; +import com.forgon.tools.hibernate.ObjectDao; +import com.forgon.tools.util.ConfigUtils; + +public class HIPMessageWebServiceImpl implements HIPMessageWebService{ + + private Logger logger = Logger.getLogger(this.getClass()); + @Autowired + private LogManager appLogManager; + @Autowired + private ObjectDao objectDao; + @Autowired + private ForeignTousseApplicationManager foreignTousseApplicationManager; + @Autowired + private SupplyRoomConfigManager supplyRoomConfigManager; + @Autowired + private SupplierManager supplierManager; + @Autowired + private OrgUnitManager orgUnitManager; + + /** + * typeCode为处理结果,AA表示成功 + */ + private static final String TYPE_CODE_SUCCESS = "AA"; + + /** + * typeCode为处理结果,AE表示失败 + */ + private static final String TYPE_CODE_FAIL = "AE"; + + /** + * 服务名称:HIP0050 + */ + private static final String SERVICE_NAME = "HIP0050"; + + @SuppressWarnings("unchecked") + @Override + public String HIPMessageServer(String action, String messageBody) { + logger.debug("调用外来器械包接口的HIPMessageServer方法,参数action=" + action + ",message = " + messageBody); + appLogManager.saveLog(AcegiHelper.getLoginUser(), "调用接口" , Log.TYPE_QUERY, "调用外来器械包接口的HIPMessageServer方法,请求信息=" + messageBody); + String sender = ""; + String receiver = ""; + String requestMsgId = ""; + if(StringUtils.isEmpty(action)){ + return buildReturnMessage(TYPE_CODE_FAIL, "action不能为空!", sender, receiver, requestMsgId); + } + if(StringUtils.isEmpty(messageBody)){ + return buildReturnMessage(TYPE_CODE_FAIL, "message不能为空!", sender, receiver, requestMsgId); + } + if(!StringUtils.equals(action, SERVICE_NAME)){ + return buildReturnMessage(TYPE_CODE_FAIL, "action错误!", sender, receiver, requestMsgId); + } + String typeCode = TYPE_CODE_SUCCESS; + String acknowledgementDetail = ""; + try { + messageBody = StringEscapeUtils.unescapeHtml(messageBody); + int beginIndex = messageBody.indexOf(""); + if(beginIndex == -1 || endIndex == -1){ + return buildReturnMessage(TYPE_CODE_FAIL, "节点不存在!", sender, receiver, requestMsgId); + } + messageBody = messageBody.substring(beginIndex, endIndex + "".length()); + Document document = DocumentHelper.parseText(messageBody.trim()); + Map nameSpaceURIMap = new HashMap(); + nameSpaceURIMap.put("s", "urn:hl7-org:v3"); + + //请求消息ID,作为响应消息/acknowledgement/targetMessage/id/@extension节点的取值 + String idXpath = "/POOR_HIP0050/s:id/@extension"; + requestMsgId = this.processDataByXpath(document, nameSpaceURIMap, idXpath); + + //请求消息的接受者,返回消息的发送者 + String senderXpath = "/POOR_HIP0050/s:receiver/s:device/s:id/s:item/@extension"; + sender = this.processDataByXpath(document, nameSpaceURIMap, senderXpath); + + //请求消息的发送者,返回消息的接受者 + String receiverXpath = "/POOR_HIP0050/s:sender/s:device/s:id/s:item/@extension"; + receiver = this.processDataByXpath(document, nameSpaceURIMap, receiverXpath); + + //subject节点可以有多个,一个节点代表一个手术申请单 + String subjectXpath = "/POOR_HIP0050/s:controlActProcess/s:subject"; + XPath xpath = document.createXPath(subjectXpath); + xpath.setNamespaceURIs(nameSpaceURIMap); + List subjectNodeList = xpath.selectNodes(document, xpath); + if(CollectionUtils.isEmpty(subjectNodeList)){ + return buildReturnMessage(TYPE_CODE_FAIL, "/controlActProcess/subject节点不存在!", sender, receiver, requestMsgId); + } + + for(int i=1;i<=subjectNodeList.size();i++){ + + //一个手术申请单包含多个手术 多个手术可以循环,循环节点component2,每台手术单独生成一张外来器械包申请单 + String component2NodeXpathStr = subjectXpath + "[" + i + "]/s:procedureRequest/s:component2"; + XPath component2NodeXpath = document.createXPath(component2NodeXpathStr); + component2NodeXpath.setNamespaceURIs(nameSpaceURIMap); + List performerNodeList = component2NodeXpath.selectNodes(document, component2NodeXpath); + + if(CollectionUtils.isEmpty(performerNodeList)){ + return buildReturnMessage(TYPE_CODE_FAIL, "/controlActProcess/subject/procedureRequest/component2节点不存在!", sender, receiver, requestMsgId); + } + + for(int j=1;j<=performerNodeList.size();j++){ + //执行科室 + String representedOrganizationCodeXpath = subjectXpath + "[" + i + "]/s:procedureRequest/s:component2[" + j + "]/s:procedureRequest/s:performer/s:assignedEntity/s:representedOrganization/s:id/s:item/@extension"; + String representedOrganizationCode = this.processDataByXpath(document, nameSpaceURIMap, representedOrganizationCodeXpath); + //申请人 + String applicantXpath = subjectXpath + "[" + i + "]/s:procedureRequest/s:author/s:assignedEntity/s:assignedPerson/s:name/s:item/s:part/@value"; + String applicant = processDataByXpath(document, nameSpaceURIMap, applicantXpath); + //申请时间 + String appTimeXpath = subjectXpath + "[" + i + "]/s:procedureRequest/s:effectiveTime/s:low/@value"; + String applicationTime = processDataByXpath(document, nameSpaceURIMap, appTimeXpath); + + //String representedOrganizationName = ""; + //预定手术时间 + String operationTimeXpath = subjectXpath + "[" + i + "]/s:procedureRequest/s:component2[" + j + "]/s:procedureRequest/s:performer/s:time/s:low/@value"; + String operationTime = this.processDataByXpath(document, nameSpaceURIMap, operationTimeXpath); + //手术名称 + String operationXpath = subjectXpath + "[" + i + "]/s:procedureRequest/s:component2[" + j + "]/s:procedureRequest/s:code/s:displayName/@value"; + String operation = this.processDataByXpath(document, nameSpaceURIMap, operationXpath); + //器械包名称 + String packageNameXpath = subjectXpath + "[" + i + "]/s:procedureRequest/s:component2[" + j + "]/s:procedureRequest/s:Package/s:packageName/@extension"; + String tousseName = this.processDataByXpath(document, nameSpaceURIMap, packageNameXpath); + //供应商 + String venNameXpath = subjectXpath + "[" + i + "]/s:procedureRequest/s:component2[" + j + "]/s:procedureRequest/s:Package/s:venName/@extension"; + String supplierName = this.processDataByXpath(document, nameSpaceURIMap, venNameXpath); + //器械包数量 + String amountXpath = subjectXpath + "[" + i + "]/s:procedureRequest/s:component2[" + j + "]/s:procedureRequest/s:Package/s:amount/@extension"; + String amount = this.processDataByXpath(document, nameSpaceURIMap, amountXpath); + + //住院号 + String hospitalNumberXpath = subjectXpath + "[" + i + "]/s:procedureRequest/s:componentOf1/s:encounter/s:subject/s:patient/s:id/s:item[@root='2.16.156.10011.1.12']/@extension"; + String hospitalNumber = this.processDataByXpath(document, nameSpaceURIMap, hospitalNumberXpath); + + //患者姓名 + String patientNameXpath = subjectXpath + "[" + i + "]/s:procedureRequest/s:componentOf1/s:encounter/s:subject/s:patient/s:patientPerson/s:name/s:item/s:part/@value"; + String patientName = this.processDataByXpath(document, nameSpaceURIMap, patientNameXpath); + + //性别代码 + String sexXpath = subjectXpath + "[" + i + "]/s:procedureRequest/s:componentOf1/s:encounter/s:subject/s:patient/s:patientPerson/s:administrativeGenderCode/s:displayName/@value"; + String sex = this.processDataByXpath(document, nameSpaceURIMap, sexXpath); + if(StringUtils.isNotBlank(sex)){ + sex = sex.replaceAll("性", ""); + } + + //出生日期-派生年龄 + String ageXpath = subjectXpath + "[" + i + "]/s:procedureRequest/s:componentOf1/s:encounter/s:subject/s:patient/s:patientPerson/s:birthTime/s:originalText/@value"; + String age = this.processDataByXpath(document, nameSpaceURIMap, ageXpath); + if(StringUtils.isNotBlank(age)){ + age = age.replaceAll("岁", ""); + } + + //科室名称 + String ascriptionDepartmentXpath = subjectXpath + "[" + i + "]/s:procedureRequest/s:componentOf1/s:encounter/s:location/s:serviceDeliveryLocation/s:serviceProviderOrganization/s:name/s:item/s:part/@value"; + String ascriptionDepartment = this.processDataByXpath(document, nameSpaceURIMap, ascriptionDepartmentXpath); + + //保存外来器械包申请单 + if(StringUtils.isBlank(representedOrganizationCode)){ + throw new SystemException("执行科室编码不能为空!"); + } + + OrgUnit orgUnit = orgUnitManager.getByCode(representedOrganizationCode); + if(orgUnit == null){ + throw new SystemException("执行科室不存在,请联系管理员!"); + } + + if(StringUtils.isBlank(applicant)){ + throw new SystemException("申请人不能为空!"); + } + if(StringUtils.isBlank(tousseName)){ + throw new SystemException("器械包名称不能为空!"); + } + if(StringUtils.isBlank(supplierName)){ + throw new SystemException("供应商不能为空!"); + } + if(!DatabaseUtil.isPoIdValid(amount)){ + throw new SystemException("器械包数量不能为空!"); + } + + // true:显示原始的包定义;false或者没有配置:显示最近一次申请的包定义 + boolean isShowForeignTousseAncestorDefinitionForApply = + ConfigUtils.getSystemSetConfigByNameBool("isShowForeignTousseAncestorDefinitionForApply"); + SupplyRoomConfig supplyRoomConfig = supplyRoomConfigManager.getSystemParamsObj(); + String hql = String.format("select po from %s po where po.tousseType = '%s' and po.name = '%s' and po.supplierName = '%s' ", + TousseDefinition.class.getSimpleName(), TousseDefinition.PACKAGE_TYPE_FOREIGN, + tousseName, supplierName==null?"":supplierName); + if(isShowForeignTousseAncestorDefinitionForApply){ + hql += " and po.forDisplay = 1 "; + } + hql += " order by po.id desc "; + List tousseList = objectDao.findByHql(hql); + TousseDefinition tousseDefinition = new TousseDefinition(); + if(CollectionUtils.isNotEmpty(tousseList)){ + tousseDefinition = tousseList.get(0); + } + //外来器械包 + JSONArray jsonArray = new JSONArray(); + // 材料 + JSONArray materialArr = buildDefaultMaterial(tousseDefinition); + Integer appAmount = Integer.valueOf(amount); + for(int k=0; k 0){ + //根据供应商名称及厂商类型查询供应商 + if(StringUtils.isNotBlank(supplierName)){ + Supplier supplier = supplierManager.getFirst(" companyName = '"+ supplierName +"' and rentTousse = '"+ Supplier.SUPPLIER_TYPE_RENTTOUSSE +"'"); + if(supplier != null){ + supplierContactUser = supplier.getContact(); + supplierContactPhone = supplier.getCellPhone(); + }else{ + supplier = new Supplier(); + supplier.setCompanyName(supplierName); + supplier.setIsManufacturer(false); + supplier.setIsSupplier(false); + supplier.setRentTousse(Supplier.SUPPLIER_TYPE_RENTTOUSSE); + supplierManager.saveOrUpdate(supplier); + } + } + } + + String foreignTousseInfo = jsonArray.toString(); + ForeignTousseApplication foreignTousseApplication = new ForeignTousseApplication(); + foreignTousseApplication.setIsInterfacePush(Constants.STR_YES); + foreignTousseApplication.setType(InvoicePlan.TYPE_FOREIGNTOUSSEAPPLIACTION); + foreignTousseApplication.setApplicant(applicant); + foreignTousseApplication.setDepart(orgUnit.getName()); + foreignTousseApplication.setDepartCoding(orgUnit.getOrgUnitCoding()); + foreignTousseApplication.setSettleAccountsDepart(orgUnit.getName()); + foreignTousseApplication.setSettleAccountsDepartCoding(orgUnit.getOrgUnitCoding()); + Date applicationTimeDate = new Date(); + if(StringUtils.isNotBlank(applicationTime)){ + applicationTimeDate = DateTools.coverStrToDate(applicationTime, "yyyyMMddHHmmss"); + if(applicationTimeDate == null){ + throw new SystemException("申请日期格式必须为yyyyMMddHHmmss!"); + } + } + foreignTousseApplication.setApplicationTime(applicationTimeDate); + foreignTousseApplication.setSurgery(operation); + + Date operationTimeDate = null; + if(StringUtils.isNotBlank(operationTime)){ + operationTimeDate = DateTools.coverStrToDate(operationTime, "yyyyMMddHHmmss"); + if(operationTimeDate == null){ + throw new SystemException("预订手术时间日期格式必须为yyyyMMddHHmmss!"); + } + } + foreignTousseApplication.setOperationTime(operationTimeDate); + foreignTousseApplication.setPackageStatus(InvoicePlan.RECYCLINGSTATUS_AWAITRECEIVE); + foreignTousseApplication.setOrderByFiled(InvoicePlan.DELIVER_AWAITDELIVER); + // 设置五笔码和拼音码 + foreignTousseApplication.setSpelling(GB2Alpha.string2Alpha(foreignTousseApplication.getDepart())); + foreignTousseApplication.setWbCode(GB2WB.getWBCode(foreignTousseApplication.getDepart())); + //设置外来器械申请单的供应商联系人与联系电话 + foreignTousseApplication.setSupplierContactName(supplierContactUser); + foreignTousseApplication.setSupplierPhoneNumber(supplierContactPhone); + + //患者信息 + foreignTousseApplication.setHospitalNumber(hospitalNumber); + foreignTousseApplication.setPatient(patientName); + foreignTousseApplication.setPatientAge(age); + foreignTousseApplication.setPatientSex(sex); + foreignTousseApplication.setAscriptionDepartment(ascriptionDepartment); + + //暂存接口提交的申请单 + foreignTousseApplication.setCommittedStatus(false); + + foreignTousseApplicationManager.saveOrUpdate(null, foreignTousseApplication, foreignTousseInfo, ForeignTousseApplication.ACTION_TYPE_ADD); + } + } + } catch (Exception e) { + typeCode = TYPE_CODE_FAIL; + acknowledgementDetail = "保存失败:" + e.getMessage(); + e.printStackTrace(); + } + + return buildReturnMessage(typeCode, acknowledgementDetail, sender, receiver, requestMsgId); + } + + /** + * 获取默认材料明细列表,包定义存在则返回包定义的材料明细;不存在则返回默认材料明细(工具*1、植入物*1) + * @param tousseDefinition + * @return + */ + private JSONArray buildDefaultMaterial(TousseDefinition tousseDefinition) { + JSONArray materialArr = new JSONArray(); + if(tousseDefinition != null && DatabaseUtil.isPoIdValid(tousseDefinition.getId())){ + List materialInstances = tousseDefinition.getMaterialInstances(); + if(CollectionUtils.isNotEmpty(materialInstances)){ + for (MaterialInstance materialInstance : materialInstances) { + MaterialDefinition md = materialInstance.getMaterialDefinition(); + if(md == null){ + continue; + } + JSONObject json = new JSONObject(); + json.put("materialName", md.getName()); + json.put("amount", materialInstance.getCount()); + json.put("includeImplant", StringUtils.defaultString(md.getIsImplant(), Constants.STR_NO)); + materialArr.add(json); + } + if(materialArr.size() > 0){ + return materialArr; + } + } + } + //默认材料明细,一套工具和一套植入物 + JSONObject toolJson = new JSONObject(); + toolJson.put("materialName", MaterialDefinition.MATERIAL_TOOS); + toolJson.put("amount", 1); + toolJson.put("includeImplant", Constants.STR_NO); + materialArr.add(toolJson); + JSONObject implantJson = new JSONObject(); + implantJson.put("materialName", MaterialDefinition.MATERIAL_IMPLANT); + implantJson.put("amount", 1); + implantJson.put("includeImplant", Constants.STR_YES); + materialArr.add(implantJson); + return materialArr; + } + + /** + * 构建返回信息 + * @param typeCodeFail 处理结果,AA表示成功 AE表示失败 + * @param acknowledgementDetail 处理结果说明 + * @return + */ + private String buildReturnMessage(String typeCode, String acknowledgementDetail, String sender, String receiver, String requestMsgId) { + if(StringUtils.isBlank(typeCode)){ + return null; + } + StringBuffer returnMessageBuffer = new StringBuffer(); + returnMessageBuffer.append(" "); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(" "); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + returnMessageBuffer.append(""); + logger.debug("调用外来器械包接口的HIPMessageServer方法,返回结果=" + returnMessageBuffer.toString()); + appLogManager.saveLog(AcegiHelper.getLoginUser(), "调用接口" , Log.TYPE_QUERY, "调用外来器械包接口的HIPMessageServer方法,返回结果=" + returnMessageBuffer.toString()); + return returnMessageBuffer.toString(); + } + + /** + * 根据document和Xpath表达式解析数据 + * @param document + * @param nameSpaceURIMap + * @param xpathExp + * @return + */ + private String processDataByXpath(Document document, Map nameSpaceURIMap, String xpathExp) { + if ((StringUtils.isNotBlank(xpathExp)) && (document != null) && (nameSpaceURIMap != null)) { + XPath xpath = document.createXPath(xpathExp); + xpath.setNamespaceURIs(nameSpaceURIMap); + Node node = xpath.selectSingleNode(document); + if (node != null) { + return node.getStringValue(); + } + } + return null; + } + +} Index: ssts-web/src/main/webapp/disinfectsystem/config/qysrmyy/spring/webservice-cxf.xml =================================================================== diff -u --- ssts-web/src/main/webapp/disinfectsystem/config/qysrmyy/spring/webservice-cxf.xml (revision 0) +++ ssts-web/src/main/webapp/disinfectsystem/config/qysrmyy/spring/webservice-cxf.xml (revision 35795) @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + \ No newline at end of file