package nckd.fi.er.task; import com.alibaba.dubbo.common.utils.CollectionUtils; import kd.bos.context.RequestContext; import kd.bos.dataentity.entity.DynamicObject; import kd.bos.dataentity.entity.DynamicObjectCollection; import kd.bos.exception.KDBizException; import kd.bos.exception.KDException; import kd.bos.krpc.common.logger.Logger; import kd.bos.krpc.common.logger.LoggerFactory; import kd.bos.list.ListShowParameter; import kd.bos.orm.query.QCP; import kd.bos.orm.query.QFilter; import kd.bos.schedule.executor.AbstractTask; import kd.bos.servicehelper.BusinessDataServiceHelper; import kd.bos.servicehelper.QueryServiceHelper; import kd.bos.servicehelper.operation.SaveServiceHelper; import kd.bos.servicehelper.user.UserServiceHelper; import nckd.base.common.utils.DateUtil; import nckd.base.common.utils.ParamUtils; import nckd.base.common.utils.TripSyncUtils; import org.apache.commons.lang3.ObjectUtils; import org.jetbrains.annotations.NotNull; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; import java.util.Map; public class MonthlySettlementBillTask extends AbstractTask { private static Logger log = LoggerFactory.getLogger(MonthlySettlementBillTask.class); /** * 总页码,不处理总数, * 每当当前页码数据小于1000 停止接口查询 */ private final static int totalPage = 1000; /** * 每页条数,最多500条 实际1000条 */ private final static int size = 1000; private Date parseStringToDateWithSdf(String dateStr) { if (ObjectUtils.isEmpty(dateStr)) { return null; } // 每次新建SimpleDateFormat,避免线程安全问题 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { return sdf.parse(dateStr); } catch (ParseException e) { return null; } } private Date parseStringToDateWithSdfMonth(String dateStr) { if (ObjectUtils.isEmpty(dateStr)) { return null; } // 每次新建SimpleDateFormat,避免线程安全问题 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM"); try { return sdf.parse(dateStr); } catch (ParseException e) { return null; } } @Override public void execute(RequestContext requestContext, Map map) throws KDException { log.info("月结账单同步调度计划开始执行"); List> resultLists = getResult(); if (ObjectUtils.isEmpty(resultLists)){ log.info("月结账单查询接口 暂无数据-----"); return ; } List ids = new ArrayList<>(); for (Map resultMap : resultLists) { //供应商名称-供应商编号 Object service = resultMap.get("supplierNo"); //账单编号-订单号 Object billnum = resultMap.get("orderNo"); //费用承担公司.ID-法人公司 Object settlemain = resultMap.get("frgs"); //服务类型-订单类型 Object operationtype = resultMap.get("orderType"); //币种 Object currency = resultMap.get("settlementCurrency"); //结算金额 Object settlementamount = resultMap.get("settlementAmount"); //账单起始日-预订时间 Object periodstartdate = resultMap.get("orderDate"); //账单截止日-出票时间 Object periodenddate = resultMap.get("printTicketTime"); //发票类型 - 供应商发票类型,枚举 为空/0:普票 1:专票 Object invoicetype = resultMap.get("supplierInvoiceType"); //发票代码-结算批次号(对应系统账单号) Object invoicecode = resultMap.get("accCheckBatchNo"); //发票号码 -结算明细主键 Object invoiceno = resultMap.get("tmcSettlementid"); //行程单/火车票- orderType Object flightitineraryandtrain = resultMap.get("searchType"); //价税合计-结算单合计金额 Object totalamount = resultMap.get("totalAmount"); //税额 Object taxamount_invoice = resultMap.get("taxAmount"); //结算单号 Object checkingbillno = resultMap.get("settlementNo"); //旅客姓名-出行人姓名 Object passengername = resultMap.get("guestName"); //出发地-出发城市名称 Object invoicefromcity = resultMap.get("departCityName"); //目的地-到达城市名称/酒店所在城市 Object invoicetocity = resultMap.get("arrivalCityName"); //收票公司-法人公司名称 Object buyerorgname = resultMap.get("frgsmc"); //开票公司-酒店名称/航空公司名称 Object makeoutcompname = resultMap.get("hotelName")==null ? resultMap.get("airlineCompanyName") : resultMap.get("hotelName"); //下载地址-违背事项 Object downloadurl = resultMap.get("violationMatter"); //电子客票号-票号 Object ticketno = resultMap.get("ticketNo"); //订单类型-订单类型 Object orderstatus = resultMap.get("orderType"); //内部下载地址-违背原因说明 Object innerdownloadurl = resultMap.get("violationCause"); //出发时间 Object departtime = resultMap.get("takeOffTime"); //业务发生时间 Object rebookingTime = resultMap.get("rebookingtime"); //航班号/车次号-机票航班号/车票车次 Object number = resultMap.get("flight")==null ? resultMap.get("ticketInfoID") : resultMap.get("flight"); //国内/国外 Object international = resultMap.get("international"); //测试用例 // Object invoicefromcity = resultMap.get("cityName"); // Object invoiceno = resultMap.get("subAccCheckBatchNo"); // Object departtime = resultMap.get("startTime"); // Object number = resultMap.get("tmcSettlementid"); DynamicObject dynamicBillObj = BusinessDataServiceHelper.newDynamicObject("er_checkingbill"); //供应商名称 dynamicBillObj.set("server", service); //账单编号 dynamicBillObj.set("billnum", billnum); //费用承担公司 QFilter[] filters = new QFilter[]{ new QFilter("number", QCP.equals, "C01"), }; // 执行查询 DynamicObject conflictBills = BusinessDataServiceHelper.loadSingle( "bos_org", "id", filters ); dynamicBillObj.set("settlemain", conflictBills); String s = null; switch (operationtype.toString()){ case "01001": case "01002": case "01003": if ("1".equals(international.toString())){ s = "2"; }else { s = "4"; } break; case "1": case "2": case "3": s = "6"; break; } //服务类型 dynamicBillObj.set("operationtype", s); //单据状态 dynamicBillObj.set("billstatusname", "4"); //币种 switch (currency.toString()){ case "CNY": dynamicBillObj.set("currency", "1"); break; case "HKD": dynamicBillObj.set("currency", "2"); break; case "JPY": dynamicBillObj.set("currency", "3"); break; case "USD": dynamicBillObj.set("currency", "4"); break; case "EUR": dynamicBillObj.set("currency", "5"); break; case "GBP": dynamicBillObj.set("currency", "6"); break; case "AUD": dynamicBillObj.set("currency", "7"); break; case "TWD": dynamicBillObj.set("currency", "8"); break; case "MOP": dynamicBillObj.set("currency", "9"); break; } //结算金额 dynamicBillObj.set("settlementamount", settlementamount); //账单起始日 String periodStartDateStr = (String)periodstartdate; Date periodStartDate = parseStringToDateWithSdf(periodStartDateStr); dynamicBillObj.set("periodstartdate", periodStartDate); //账单截止日 String periodendDateStr = (String)periodenddate; Date periodendDate = parseStringToDateWithSdf(periodendDateStr); dynamicBillObj.set("periodenddate", periodendDate); //表单ID switch (operationtype.toString()){ case "1": case "5": dynamicBillObj.set("formid", "er_hotelcheckingbill"); break; case "2": case "4": dynamicBillObj.set("formid", "er_planecheckingbill"); break; case "3": dynamicBillObj.set("formid", "er_vehiclecheckingbill"); break; case "6": dynamicBillObj.set("formid", "er_traincheckingbill"); break; } //调用发票查询接口 List> resultInvoiceLists = getInvoiceResult(checkingbillno,rebookingTime); //单据体 DynamicObjectCollection entryEntity = dynamicBillObj.getDynamicObjectCollection("invoiceentry"); if (CollectionUtils.isEmpty(resultInvoiceLists)){ log.info("结算单号:"+checkingbillno+"未查询到发票数据"); ids.add(dynamicBillObj); continue; } for (Map resultInvoiceList : resultInvoiceLists){ //单据体新增一行 DynamicObject entry =entryEntity.addNew(); //单据体字段赋值 String invoice = getInvoiceType(resultInvoiceList); entry.set("invoicetype",invoice); //发票代码 entry.set("invoicecode", resultInvoiceList.get("invoiceCode")); //发票号码 entry.set("invoiceno", resultInvoiceList.get("invoiceNumber")); //行程单/火车票 entry.set("flightitineraryandtrain",flightitineraryandtrain.equals("0100") || flightitineraryandtrain.equals("0200")); //价税合计 entry.set("totalamount", resultInvoiceList.get("invoiceAmount")); //税额 entry.set("taxamount_invoice", resultInvoiceList.get("invoiceTax")); //结算单号 entry.set("checkingbillno", checkingbillno); //旅客 entry.set("passengername", passengername); //出发地 entry.set("invoicefromcity", invoicefromcity); //目的地 entry.set("invoicetocity", invoicetocity); //收票公司 entry.set("buyerorgname", buyerorgname); //开票公司 entry.set("makeoutcompname", makeoutcompname); //下载地址 entry.set("downloadurl", resultInvoiceList.get("invoiceUrl")); //电子客票号 entry.set("ticketno", ticketno); //订单类型 entry.set("orderstatus",orderstatus); //测试 // entry.set("orderstatus","O"); //内部下载地址 entry.set("innerdownloadurl", resultInvoiceList.get("invoiceUrl")); //出发时间 entry.set("departtime", departtime); //航班号/车次号 entry.set("number", number); //保存 ids.add(dynamicBillObj); } } SaveServiceHelper.save(ids.toArray(new DynamicObject[0])); } private static @NotNull String getInvoiceType(Map resultInvoiceList) { //发票类型 String invoice= ""; if (ObjectUtils.isNotEmpty(resultInvoiceList.get("invoiceType"))){ switch (resultInvoiceList.get("invoiceType").toString()){ case "air_ticket": case "air_e_ticket": //行程单 invoice = "4"; break; case "e_vat_invoice": //全电发票(普票) invoice = "9"; break; case "e_vats_invoice": //全电发票(专票) invoice = "8"; break; case "quota_invoice": //定额发票 invoice = "6"; break; case "train_ticket": case "train_ticket_refund": //火车票/退票 invoice = "5"; break; case "vat_invoice": //增值税普通发票 invoice = "2"; break; case "vate_invoice": //增值税电子普通发票 invoice = "1"; break; case "vats_invoice": //增值税专用发票 invoice = "3"; break; case "railway_e_ticket": case "railway_e_ticket_re": //铁路电子客票 //铁路电子客票退票 invoice = "29"; break; default: invoice = "999"; }; } return invoice; } /** * @return 获取月结账单列表 */ private List> getResult() { //获取开始同步时间 String syncTime = getSyncTime(); log.info("月结账单同步开始时间:" + syncTime); Date nowDate = new Date(); String nowDateString = DateUtil.date2str(nowDate, DateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS); List> dataList = new ArrayList<>(); for (int i = 0; i < totalPage; i++) { //创建接口业务数据参数 Map data = new HashMap<>(); data.put("dateFrom", syncTime); //测试 // data.put("dateFrom", "1997-01-01"); data.put("dateTo",nowDateString); //当前页 data.put("current", i + 1); //每页条数,最多500条 data.put("size", size); data.put("enterpriseNo", "JXWL"); data.put("settlementType", "02"); Map resp = TripSyncUtils.pushApiCallResult("FCSET_OUTAPI_LiteGetSettlementInfo", Boolean.TRUE, data); //报错终止同步,等待下次计划执行 if ((Boolean) resp.get("fail")) { throw new KDBizException(resp.get("message").toString()); } Map result = (Map) resp.get("result"); List> resultDataList = (List>) result.getOrDefault("settlementInfos", Collections.emptyList()); dataList.addAll(resultDataList); //当前查询数量小于分页数量时结束循环 if (resultDataList.size() < size) { break; } } return dataList; } /** * @return 获取发票明细 */ private List> getInvoiceResult(Object checkingBillNo,Object rebookingTime) { List> dataList = new ArrayList<>(); if (Objects.isNull(rebookingTime) || Objects.isNull(checkingBillNo)) { return dataList; } for (int i = 0; i < totalPage; i++) { //创建接口业务数据参数 Map data = new HashMap<>(); //当前页 data.put("current", i + 1); //每页条数,最多500条 data.put("size", size); //结算单号 data.put("settlementNo", checkingBillNo.toString()); //账期 data.put("paymentDays", parseStringToDateWithSdfMonth(rebookingTime.toString())); //企业编号 data.put("enterpriseNo","JXWL"); Map resp = TripSyncUtils.pushApiCallResult("FCSET_OUTAPI_GetInvoice", Boolean.TRUE, data); //报错终止同步,等待下次计划执行 if ((Boolean) resp.get("fail")) { throw new KDBizException(resp.get("message").toString()); } Map result = (Map) resp.get("result"); List> resultDataList = (List>) result.getOrDefault("invoices", Collections.emptyList()); dataList.addAll(resultDataList); //当前查询数量小于分页数量时结束循环 if (resultDataList.size() < size) { break; } } return dataList; } /** * @return 获取同步开始时间 */ private String getSyncTime() { //获取费用核算应用参数 Map sysCtrlParameter = ParamUtils.getSysCtrlParameter(ParamUtils.EM); //是否全量同步 Boolean isAll = (Boolean) sysCtrlParameter.get("nckd_settlementbillall"); if (isAll) { return "1970-01-01 00:00:00"; } //增量同步小时 填写整数N,同步N小时前到现在新增或修改的数据,不填默认1小时。 Integer hours = ObjectUtils.isEmpty(sysCtrlParameter.get("nckd_settlementbillhour")) ? 1 : (Integer) sysCtrlParameter.get("nckd_settlementbillhour"); //同步N小时前 Date date = DateUtil.addHour(new Date(), -hours); return DateUtil.date2str(date, DateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS); } }