|
|
@@ -1,18 +1,27 @@
|
|
|
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.exception.KDBizException;
|
|
|
import kd.bos.exception.KDException;
|
|
|
import kd.bos.krpc.common.logger.Logger;
|
|
|
import kd.bos.krpc.common.logger.LoggerFactory;
|
|
|
+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.operation.SaveServiceHelper;
|
|
|
+import kd.qmc.qcbd.common.constant.BosOrgConst;
|
|
|
+import nckd.base.common.constant.BaseFieldConst;
|
|
|
+import nckd.base.common.enums.CurrencyEnum;
|
|
|
+import nckd.base.common.enums.InvoiceTypeEnum;
|
|
|
import nckd.base.common.utils.DateUtil;
|
|
|
+import nckd.base.common.utils.InvoiceApiUtils;
|
|
|
import nckd.base.common.utils.ParamUtils;
|
|
|
import nckd.base.common.utils.TripSyncUtils;
|
|
|
import org.apache.commons.lang3.ObjectUtils;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
|
|
|
import java.util.*;
|
|
|
|
|
|
@@ -24,352 +33,466 @@ import java.util.*;
|
|
|
* @Description:结算单(国内机票)
|
|
|
*/
|
|
|
public class DomesticFlightSettlementTask extends AbstractTask {
|
|
|
- private static Logger log = LoggerFactory.getLogger(DomesticFlightSettlementTask.class);
|
|
|
+ private static final Logger log = LoggerFactory.getLogger(DomesticFlightSettlementTask.class);
|
|
|
+ /**
|
|
|
+ * 最大查询页数,当某页数据小于每页条数时停止查询
|
|
|
+ */
|
|
|
+ private static final int TOTAL_PAGE = 1000;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 每页查询条数
|
|
|
+ */
|
|
|
+ private static final int PAGE_SIZE = 1000;
|
|
|
|
|
|
/**
|
|
|
- * 总页码,不处理总数,
|
|
|
- * 每当当前页码数据小于1000 停止接口查询
|
|
|
+ * 全量同步的起始时间
|
|
|
*/
|
|
|
- private final static int totalPage = 1000;
|
|
|
+ private static final String FULL_SYNC_START_TIME = "1970-01-01 00:00:00";
|
|
|
|
|
|
/**
|
|
|
- * 每页条数,最多500条 实际1000条
|
|
|
+ * 国内机票产品类型编码
|
|
|
*/
|
|
|
- private final static int size = 1000;
|
|
|
+ private static final String DOMESTIC_FLIGHT_PRODUCT_TYPE = "0100";
|
|
|
|
|
|
+ /**
|
|
|
+ * 企业卡号
|
|
|
+ */
|
|
|
+ private static final String ENTERPRISE_NO = "JXWL";
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 外部接口名称
|
|
|
+ */
|
|
|
+ private static final String INTERFACE_NAME = "FCSET_OUTAPI_LiteGetSettlementInfo";
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 任务执行入口
|
|
|
+ *
|
|
|
+ * @param requestContext 请求上下文
|
|
|
+ * @param map 任务参数映射
|
|
|
+ * @throws KDException 执行异常
|
|
|
+ */
|
|
|
@Override
|
|
|
public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
|
|
|
- log.info("结算单(国内机票)查询接口 调度计划开始执行");
|
|
|
- List<Map<String, Object>> resultLists = getResult();
|
|
|
- if (ObjectUtils.isEmpty(resultLists)) {
|
|
|
- log.info("结算单(国内机票)查询接口 暂无数据-----");
|
|
|
- return;
|
|
|
+ log.info("国内机票结算单同步任务开始执行");
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 1. 从外部接口获取国内机票结算数据
|
|
|
+ List<Map<String, Object>> resultLists = getResult();
|
|
|
+ if (ObjectUtils.isEmpty(resultLists)) {
|
|
|
+ log.info("未获取到国内机票结算数据,任务结束");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("成功获取到 " + resultLists.size() + " 条国内机票结算数据");
|
|
|
+
|
|
|
+ // 2. 处理获取到的数据
|
|
|
+ processResultData(resultLists);
|
|
|
+
|
|
|
+ log.info("国内机票结算单同步任务执行完成");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.info("国内机票结算单同步任务执行失败", e);
|
|
|
+ throw e;
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量处理获取到的国内机票结算数据
|
|
|
+ *
|
|
|
+ * @param resultLists 国内机票结算数据列表
|
|
|
+ */
|
|
|
+ private void processResultData(List<Map<String, Object>> resultLists) {
|
|
|
+ int successCount = 0;
|
|
|
+ int failCount = 0;
|
|
|
+
|
|
|
for (Map<String, Object> resultMap : resultLists) {
|
|
|
try {
|
|
|
- // 从结果映射中提取各字段
|
|
|
- extractAndProcessFields(resultMap);
|
|
|
+ // 提取并处理单条数据字段,保存到系统
|
|
|
+ List<DynamicObject> planeCheckingList = extractAndProcessFields(resultMap);
|
|
|
+ if (!ObjectUtils.isEmpty(planeCheckingList)) {
|
|
|
+ SaveServiceHelper.save(planeCheckingList.toArray(new DynamicObject[0]));
|
|
|
+ successCount++;
|
|
|
+ }
|
|
|
} catch (Exception e) {
|
|
|
- log.info("处理火车票结算数据时发生异常,数据内容: " + resultMap, e);
|
|
|
+ failCount++;
|
|
|
+ log.info("处理国内机票结算数据时发生异常,数据内容: " + resultMap, e);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ log.info("国内机票结算数据处理完成:成功 " + successCount + " 条,失败 " + failCount + " 条");
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/**
|
|
|
- * 从单条数据映射中提取字段并处理
|
|
|
+ * 从单条数据映射中提取字段并处理,生成系统动态对象
|
|
|
+ * 注:此方法将外部接口数据映射到系统表单字段
|
|
|
*
|
|
|
* @param resultMap 单条数据映射
|
|
|
+ * @return 处理后的动态对象列表
|
|
|
*/
|
|
|
- private void extractAndProcessFields(Map<String, Object> resultMap) {
|
|
|
- // 1.获取接口返回值
|
|
|
-
|
|
|
- // ===================== 订单基本信息 =====================
|
|
|
- // 订单类型 (01001机票正常单, 01002机票退单, 01003机票改签单, 1酒店正常单, 2酒店退单等)
|
|
|
- Object orderType = resultMap.get("orderType");
|
|
|
- // 房间数
|
|
|
- Object roomQuantity = resultMap.get("roomQuantity");
|
|
|
- // 订单类型名称
|
|
|
- Object orderName = resultMap.get("orderName");
|
|
|
- // 订单号
|
|
|
- Object orderNo = resultMap.get("orderNo");
|
|
|
- // 原订单编号
|
|
|
- Object oldOrderNo = resultMap.get("oldOrderNo");
|
|
|
- // 订单状态 (已完成等)
|
|
|
- Object orderStatus = resultMap.get("orderStatus");
|
|
|
- // 预订时间
|
|
|
- Object orderDate = resultMap.get("orderDate");
|
|
|
- // 业务发生时间
|
|
|
- Object rebookingtime = resultMap.get("rebookingtime");
|
|
|
- // 结算生成时间
|
|
|
- Object createTime = resultMap.get("createTime");
|
|
|
-
|
|
|
- // ===================== 结算信息 =====================
|
|
|
- // 结算明细主键
|
|
|
- Object tmcSettlementid = resultMap.get("tmcSettlementid");
|
|
|
- // 结算单号
|
|
|
- Object settlementNo = resultMap.get("settlementNo");
|
|
|
- // 结算批次号(对应系统账单号)
|
|
|
- Object accCheckBatchNo = resultMap.get("accCheckBatchNo");
|
|
|
- // 结算明细ID
|
|
|
- Object subAccCheckBatchNo = resultMap.get("subAccCheckBatchNo");
|
|
|
- // 大表ID
|
|
|
- Object mainTableId = resultMap.get("mainTableId");
|
|
|
- // 币种 (例如CNY)
|
|
|
- Object settlementCurrency = resultMap.get("settlementCurrency");
|
|
|
- // 结算金额
|
|
|
- Object settlementAmount = resultMap.get("settlementAmount");
|
|
|
- // 结算单合计金额
|
|
|
- Object totalAmount = resultMap.get("totalAmount");
|
|
|
-
|
|
|
- // ===================== 人员信息 =====================
|
|
|
- // 出行人姓名
|
|
|
- Object guestName = resultMap.get("guestName");
|
|
|
- // 出行人名称
|
|
|
- Object passengerName = resultMap.get("passengerName");
|
|
|
- // 员工姓名
|
|
|
- Object employeeName = resultMap.get("employeeName");
|
|
|
- // 出行人工号
|
|
|
- Object employeeId = resultMap.get("employeeId");
|
|
|
- // 预订人姓名
|
|
|
- Object reserveName = resultMap.get("reserveName");
|
|
|
- // 预订人员编号
|
|
|
- Object reserveId = resultMap.get("reserveId");
|
|
|
- // 人员类型(可能是员工类型)
|
|
|
- Object personnelType = resultMap.get("personnelType");
|
|
|
-
|
|
|
- // ===================== 财务信息 =====================
|
|
|
- // 销售价
|
|
|
- Object price = resultMap.get("price");
|
|
|
- // 折扣
|
|
|
- Object priceRate = resultMap.get("priceRate");
|
|
|
- // 含税金额
|
|
|
- Object inTaxAmount = resultMap.get("inTaxAmount");
|
|
|
- // 不含税金额
|
|
|
- Object excludingtaxAmount = resultMap.get("excludingtaxAmount");
|
|
|
- // 不含税交易金额(不含税销售价)
|
|
|
- Object sellingPriceNoTax = resultMap.get("sellingPriceNoTax");
|
|
|
- // 订单不含税金额
|
|
|
- Object orderNoTaxAmount = resultMap.get("orderNoTaxAmount");
|
|
|
- // 订单税额
|
|
|
- Object orderTax = resultMap.get("orderTax");
|
|
|
- // 发票税率
|
|
|
- Object taxRate = resultMap.get("taxRate");
|
|
|
-
|
|
|
- // ===================== 费用信息 =====================
|
|
|
- // 员工自付金额
|
|
|
- Object personalPaymentAmount = resultMap.get("personalPaymentAmount");
|
|
|
- // 欠款金额
|
|
|
- Object amount = resultMap.get("amount");
|
|
|
- Object priceAmount = resultMap.get("priceAmount");
|
|
|
- // 垫款服务费
|
|
|
- Object advancePaymentAmount = resultMap.get("advancePaymentAmount");
|
|
|
- // 支付类型 (0自付、1垫付)
|
|
|
- Object payType = resultMap.get("payType");
|
|
|
- // TMC支付类型
|
|
|
- Object tmcPaymentType = resultMap.get("tmcPaymentType");
|
|
|
- // 账单类型 (M月结, S服务费)
|
|
|
- Object billType = resultMap.get("billType");
|
|
|
-
|
|
|
- // ===================== 服务费信息 =====================
|
|
|
- // TMC服务费(服务商服务费)
|
|
|
- Object spServiceFee = resultMap.get("spServiceFee");
|
|
|
- // 服务费(销售服务费)
|
|
|
- Object serviceFee = resultMap.get("serviceFee");
|
|
|
- // 技术服务费
|
|
|
- Object technologyServiceFee = resultMap.get("technologyServiceFee");
|
|
|
- // 退票费
|
|
|
- Object refund = resultMap.get("refund");
|
|
|
- // 改签费
|
|
|
- Object rebookQueryFee = resultMap.get("rebookQueryFee");
|
|
|
-
|
|
|
- // ===================== 项目信息 =====================
|
|
|
- // 项目编号
|
|
|
- Object projectNo = resultMap.get("projectNo");
|
|
|
- // 项目名称
|
|
|
- Object projectName = resultMap.get("projectName");
|
|
|
- // 业务类型编号
|
|
|
- Object businessTypeNo = resultMap.get("businessTypeNo");
|
|
|
- // 业务类型名称
|
|
|
- Object businessTypeName = resultMap.get("businessTypeName");
|
|
|
- // 费用类型编号
|
|
|
- Object feeTypeNo = resultMap.get("feeTypeNo");
|
|
|
- // 费用类型名称
|
|
|
- Object feeTypeName = resultMap.get("feeTypeName");
|
|
|
- // 差旅类型 (1因公, 0因私)
|
|
|
- Object travelType = resultMap.get("travelType");
|
|
|
- // 搜索类型名称(可能是查询条件类型)
|
|
|
- Object searchTypeName = resultMap.get("searchTypeName");
|
|
|
-
|
|
|
- // ===================== 供应商信息 =====================
|
|
|
- // 供应商编号
|
|
|
- Object supplierNo = resultMap.get("supplierNo");
|
|
|
- // 供应商名称
|
|
|
- Object supplierName = resultMap.get("supplierName");
|
|
|
- // 供应单号
|
|
|
- Object purchaseOrderNo = resultMap.get("purchaseOrderNo");
|
|
|
- // 供应商发票类型 (0/空:普票, 1:专票)
|
|
|
- Object supplierInvoiceType = resultMap.get("supplierInvoiceType");
|
|
|
- // 垫款商户编号
|
|
|
- Object advancePaymentMerchantNo = resultMap.get("advancePaymentMerchantNo");
|
|
|
- // 垫款商户名称
|
|
|
- Object advancePaymentMerchantName = resultMap.get("advancePaymentMerchantName");
|
|
|
-
|
|
|
- // ===================== 法人信息 =====================
|
|
|
- // 法人公司
|
|
|
- Object frgs = resultMap.get("frgs");
|
|
|
- // 法人公司名称
|
|
|
- Object frgsmc = resultMap.get("frgsmc");
|
|
|
-
|
|
|
- // ===================== 行程信息 =====================
|
|
|
- // 国内国际标识 (1国内, 0国际)
|
|
|
- Object international = resultMap.get("international");
|
|
|
- // 所在城市/出发城市名称
|
|
|
- Object cityName = resultMap.get("cityName");
|
|
|
- // 到达城市
|
|
|
- Object arrivalCity = resultMap.get("arrivalCity");
|
|
|
- // 到达城市名称/酒店所在城市
|
|
|
- Object arrivalCityName = resultMap.get("arrivalCityName");
|
|
|
- // 入住日期/出发时间
|
|
|
- Object startTime = resultMap.get("startTime");
|
|
|
- // 离店日期/到达时间
|
|
|
- Object endTime = resultMap.get("endTime");
|
|
|
- // 出票时间
|
|
|
- Object printTicketTime = resultMap.get("printTicketTime");
|
|
|
-
|
|
|
- // ===================== 酒店信息 =====================
|
|
|
- // 酒店名称
|
|
|
- Object hotelName = resultMap.get("hotelName");
|
|
|
- // 酒店星级
|
|
|
- Object star = resultMap.get("star");
|
|
|
- // 房型中文名称
|
|
|
- Object roomName = resultMap.get("roomName");
|
|
|
- // 间夜数
|
|
|
- Object quantity = resultMap.get("quantity");
|
|
|
-
|
|
|
- // ===================== 机票附加费 =====================
|
|
|
- // 机票建设费
|
|
|
- Object airportFee = resultMap.get("airportFee");
|
|
|
- // 保险费
|
|
|
- Object insuranceFee = resultMap.get("insuranceFee");
|
|
|
-
|
|
|
- // ===================== 其他字段 =====================
|
|
|
- // 销售价(重复字段,可根据实际情况处理)
|
|
|
- Object transAmount = resultMap.get("transAmount");
|
|
|
-
|
|
|
- // 2.机票结算单 --国内机票 创建新的动态对象
|
|
|
- DynamicObject planeCheckingBill = BusinessDataServiceHelper.newDynamicObject("er_planecheckingbill");
|
|
|
-
|
|
|
- // 3. 设置对应对象属性
|
|
|
-
|
|
|
- //订单日期
|
|
|
- planeCheckingBill.set("orderdate", orderType);
|
|
|
- //订单性质
|
|
|
- planeCheckingBill.set("isbusiness", travelType);
|
|
|
- //结算类型 2 -个人现付
|
|
|
- planeCheckingBill.set("producttype", "2");
|
|
|
- //预订人工号
|
|
|
- planeCheckingBill.set("booknum", "");
|
|
|
- //预订人姓名
|
|
|
- planeCheckingBill.set("bookedname", reserveName);
|
|
|
- //结算发生日期
|
|
|
- planeCheckingBill.set("happenddate", DateUtil.string2date((String) createTime,null));
|
|
|
- //业务类型
|
|
|
- planeCheckingBill.set("operationtype", businessTypeNo);
|
|
|
- //订单分类
|
|
|
- planeCheckingBill.set("ordersort", orderType);
|
|
|
- //订单状态
|
|
|
- planeCheckingBill.set("orderstatus", "5");
|
|
|
- //结算金额
|
|
|
- planeCheckingBill.set("totalamount", settlementAmount);
|
|
|
- //币种
|
|
|
- switch (settlementCurrency.toString()){
|
|
|
- case "CNY":
|
|
|
- planeCheckingBill.set("currency", "1");
|
|
|
- break;
|
|
|
- case "HKD":
|
|
|
- planeCheckingBill.set("currency", "2");
|
|
|
- break;
|
|
|
- case "JPY":
|
|
|
- planeCheckingBill.set("currency", "3");
|
|
|
- break;
|
|
|
- case "USD":
|
|
|
- planeCheckingBill.set("currency", "4");
|
|
|
- break;
|
|
|
- case "EUR":
|
|
|
- planeCheckingBill.set("currency", "5");
|
|
|
- break;
|
|
|
- case "GBP":
|
|
|
- planeCheckingBill.set("currency", "6");
|
|
|
- break;
|
|
|
- case "AUD":
|
|
|
- planeCheckingBill.set("currency", "7");
|
|
|
- break;
|
|
|
- case "TWD":
|
|
|
- planeCheckingBill.set("currency", "8");
|
|
|
- break;
|
|
|
- case "MOP":
|
|
|
- planeCheckingBill.set("currency", "9");
|
|
|
- break;
|
|
|
+ private List<DynamicObject> extractAndProcessFields(Map<String, Object> resultMap) {
|
|
|
+ List<DynamicObject> resultLists = new ArrayList<>();
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 1. 从结果映射中提取各字段
|
|
|
+ // ===================== 订单基本信息 =====================
|
|
|
+ // 结算单号
|
|
|
+ String settlementNo = getStringValue(resultMap, "settlementNo");
|
|
|
+ // 预订时间
|
|
|
+ String orderDate = getStringValue(resultMap, "orderDate");
|
|
|
+ // 申请单号
|
|
|
+ String tripNo = getStringValue(resultMap, "tripNo");
|
|
|
+ // 差旅类型
|
|
|
+ String travelType = getStringValue(resultMap, "travelType");
|
|
|
+ // 结算生成时间
|
|
|
+ String createTime = getStringValue(resultMap, "createTime");
|
|
|
+ // 结算金额
|
|
|
+ String settlementAmount = getStringValue(resultMap, "settlementAmount");
|
|
|
+ // 币种
|
|
|
+ String settlementCurrency = getStringValue(resultMap, "settlementCurrency");
|
|
|
+ // 结算批次号
|
|
|
+ String accCheckBatchNo = getStringValue(resultMap, "accCheckBatchNo");
|
|
|
+ // 法人公司编码
|
|
|
+ String frgs = getStringValue(resultMap, "frgs");
|
|
|
+ // 项目编号
|
|
|
+ String projectNo = getStringValue(resultMap, "projectNo");
|
|
|
+ // 国内国际标识
|
|
|
+ String international = getStringValue(resultMap, "international");
|
|
|
+ // 航空公司名称
|
|
|
+ String airlineCompanyName = getStringValue(resultMap, "airlineCompanyName");
|
|
|
+ // 票号
|
|
|
+ String ticketNo = getStringValue(resultMap, "ticketNo");
|
|
|
+ // 航班号
|
|
|
+ String flight = getStringValue(resultMap, "flight");
|
|
|
+ // 机票舱位子类
|
|
|
+ String subClass = getStringValue(resultMap, "subClass");
|
|
|
+ // 机票舱位等级
|
|
|
+ String cabinClass = getStringValue(resultMap, "cabinClass");
|
|
|
+ // 出发城市名称
|
|
|
+ String departCityName = getStringValue(resultMap, "departCityName");
|
|
|
+ // 到达城市名称
|
|
|
+ String arrivalCityName = getStringValue(resultMap, "arrivalCityName");
|
|
|
+ // 出发时间
|
|
|
+ String takeOffTime = getStringValue(resultMap, "takeOffTime");
|
|
|
+ // 到达时间
|
|
|
+ String arrivalTime = getStringValue(resultMap, "arrivalTime");
|
|
|
+ // 机票价格
|
|
|
+ String price = getStringValue(resultMap, "price");
|
|
|
+ // 折扣
|
|
|
+ String priceRate = getStringValue(resultMap, "priceRate");
|
|
|
+ // 订单税额
|
|
|
+ String orderTax = getStringValue(resultMap, "orderTax");
|
|
|
+ // 机票燃油费
|
|
|
+ String tax = getStringValue(resultMap, "tax");
|
|
|
+ // 服务费
|
|
|
+ String serviceFee = getStringValue(resultMap, "serviceFee");
|
|
|
+ // 退票费
|
|
|
+ String refund = getStringValue(resultMap, "refund");
|
|
|
+ // 改签费
|
|
|
+ String rebookQueryFee = getStringValue(resultMap, "rebookQueryFee");
|
|
|
+ // 保险费
|
|
|
+ String insuranceFee = getStringValue(resultMap, "insuranceFee");
|
|
|
+ // 机票建设费
|
|
|
+ String airportFee = getStringValue(resultMap, "airportFee");
|
|
|
+
|
|
|
+ // ===================== 人员信息 =====================
|
|
|
+ // 出行人姓名
|
|
|
+ String guestName = getStringValue(resultMap, "guestName");
|
|
|
+ // 出行人工号
|
|
|
+ String employeeId = getStringValue(resultMap, "employeeId");
|
|
|
+ // 预订人姓名
|
|
|
+ String reserveName = getStringValue(resultMap, "reserveName");
|
|
|
+ // 订单号
|
|
|
+ String orderNo = getStringValue(resultMap, "orderNo");
|
|
|
+ //业务发生时间
|
|
|
+ String rebookingtime = getStringValue(resultMap, "rebookingtime");
|
|
|
+
|
|
|
+ // 订单类型
|
|
|
+ String orderType = getStringValue(resultMap, "orderType");
|
|
|
+
|
|
|
+ // 01001机票正常单01002机票退单01003机票改签单
|
|
|
+ if ("01001".equals(orderType)) {
|
|
|
+ orderType = "O";
|
|
|
+ } else if ("01002".equals(orderType)) {
|
|
|
+ orderType = "T";
|
|
|
+ } else if ("01003".equals(orderType)) {
|
|
|
+ orderType = "G";
|
|
|
+ } else {
|
|
|
+ orderType = "";
|
|
|
+ }
|
|
|
+
|
|
|
+ //结算类型
|
|
|
+ String tmcPaymentType = getStringValue(resultMap, "tmcPaymentType");
|
|
|
+ if ("公司月结".equals(tmcPaymentType)) {
|
|
|
+ tmcPaymentType = "1";
|
|
|
+ } else if ("个人现付".equals(tmcPaymentType)) {
|
|
|
+ tmcPaymentType = "2";
|
|
|
+ }
|
|
|
+ //预订人员编号
|
|
|
+ String reserveId = getStringValue(resultMap, "reserveId");
|
|
|
+ // 2. 转换差旅类型格式
|
|
|
+ if ("因公".equals(travelType)) {
|
|
|
+ travelType = "1";
|
|
|
+ } else if ("因私".equals(travelType)) {
|
|
|
+ travelType = "0";
|
|
|
+ }
|
|
|
+ // 订单状态
|
|
|
+ String orderStatus = getStringValue(resultMap, "orderStatus");
|
|
|
+ switch (orderStatus) {
|
|
|
+ case "已完成":
|
|
|
+ orderStatus = "USED";
|
|
|
+ break;
|
|
|
+ case "已预订":
|
|
|
+ orderStatus = "20000";
|
|
|
+ break;
|
|
|
+ case "已出票":
|
|
|
+ orderStatus = "40000";
|
|
|
+ break;
|
|
|
+ case "取消中":
|
|
|
+ orderStatus = "31000";
|
|
|
+ break;
|
|
|
+ case "已取消":
|
|
|
+ orderStatus = "30000";
|
|
|
+ break;
|
|
|
+ case "退票中":
|
|
|
+ orderStatus = "50201";
|
|
|
+ break;
|
|
|
+ case "改签中":
|
|
|
+ orderStatus = "50301";
|
|
|
+ break;
|
|
|
+ case "已改签":
|
|
|
+ orderStatus = "50302";
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ orderStatus = "9999";
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ // 3. 检查结算单是否已存在,存在则修改,不存在则创建
|
|
|
+ DynamicObject planeCheckingBill = queryPlaneCheckingBill(settlementNo);
|
|
|
+ boolean isNew = ObjectUtils.isEmpty(planeCheckingBill);
|
|
|
+
|
|
|
+ if (isNew) {
|
|
|
+ planeCheckingBill = BusinessDataServiceHelper.newDynamicObject("er_planecheckingbill");
|
|
|
+ log.info("结算单号 " + settlementNo + " 不存在,创建新记录");
|
|
|
+ } else {
|
|
|
+ log.info("结算单号 " + settlementNo + " 已存在,更新记录");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 设置各字段值
|
|
|
+ // ===================== 基础信息 =====================
|
|
|
+ // 订单日期
|
|
|
+ planeCheckingBill.set("orderdate", DateUtil.string2date(orderDate, null));
|
|
|
+ // 结算单号
|
|
|
+ planeCheckingBill.set("ordernum", settlementNo);
|
|
|
+ // 订单类型,固定为"O"
|
|
|
+ planeCheckingBill.set("ordertype", orderType);
|
|
|
+ // 申请单号
|
|
|
+ planeCheckingBill.set("oabillnum", tripNo);
|
|
|
+ // 报销单号
|
|
|
+ planeCheckingBill.set("reimbursenum", "");
|
|
|
+ // 订单分类(国内/国际)
|
|
|
+ planeCheckingBill.set("ordersort", international);
|
|
|
+ // 订单性质(因公/因私)
|
|
|
+ planeCheckingBill.set("isbusiness", travelType);
|
|
|
+ // 结算类型:
|
|
|
+ planeCheckingBill.set("producttype", tmcPaymentType);
|
|
|
+
|
|
|
+ // 预订人
|
|
|
+ DynamicObject sourcebookedids = queryBosUser(reserveId);
|
|
|
+ planeCheckingBill.set("sourcebookedid", sourcebookedids);
|
|
|
+ // 预订人姓名
|
|
|
+ String bookedname = ObjectUtils.isEmpty(sourcebookedids) ? "" : sourcebookedids.getString("name");
|
|
|
+ planeCheckingBill.set("bookedname", bookedname);
|
|
|
+ // 结算发生日期
|
|
|
+ planeCheckingBill.set("happenddate", DateUtil.string2date(createTime, null));
|
|
|
+ // 业务类型:2-国内机票
|
|
|
+ planeCheckingBill.set("operationtype", "2");
|
|
|
+ // 订单状态
|
|
|
+ planeCheckingBill.set("orderstatus",orderStatus);
|
|
|
+ // 父订单号
|
|
|
+ planeCheckingBill.set("parentordernum", orderNo);
|
|
|
+ // 结算金额
|
|
|
+ planeCheckingBill.set("totalamount", settlementAmount);
|
|
|
+ // ===================== 财务信息 =====================
|
|
|
+ // 设置币种,从枚举中获取对应的值
|
|
|
+ String currency = Optional.ofNullable(CurrencyEnum.getByCode(settlementCurrency))
|
|
|
+ .map(CurrencyEnum::getValue)
|
|
|
+ .orElse(null);
|
|
|
+ planeCheckingBill.set("currency", currency);
|
|
|
+ // 结算批次号
|
|
|
+ planeCheckingBill.set("batchno", accCheckBatchNo);
|
|
|
+ // 结算子批次号
|
|
|
+ planeCheckingBill.set("subbatchno", "");
|
|
|
+
|
|
|
+ // ===================== 组织信息 =====================
|
|
|
+ // 设置费用承担公司(根据法人公司编码查询组织信息)
|
|
|
+ if (StringUtils.isNotBlank(frgs)) {
|
|
|
+ QFilter[] orgFilter = new QFilter[]{
|
|
|
+ new QFilter(BaseFieldConst.NUMBER, QCP.equals, frgs),
|
|
|
+ };
|
|
|
+ DynamicObject org = BusinessDataServiceHelper.loadSingle(BosOrgConst.BOS_ORG, "id", orgFilter);
|
|
|
+ if (ObjectUtils.isEmpty(org)) {
|
|
|
+ planeCheckingBill.set("settlemain", "");
|
|
|
+ log.info("未找到编码为 " + frgs + " 的组织信息");
|
|
|
+ } else {
|
|
|
+ planeCheckingBill.set("settlemain", org);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ planeCheckingBill.set("settlemain", "");
|
|
|
+ }
|
|
|
+ // 费用承担部门
|
|
|
+ planeCheckingBill.set("settledept", "");
|
|
|
+ // 申请人公司
|
|
|
+ planeCheckingBill.set("company", "");
|
|
|
+ // 申请人部门
|
|
|
+ planeCheckingBill.set("org", "");
|
|
|
+ // 项目
|
|
|
+ planeCheckingBill.set("std_project", projectNo);
|
|
|
+ // 成本中心
|
|
|
+ planeCheckingBill.set("std_costcenter", "");
|
|
|
+ // 外部系统结算单号
|
|
|
+ planeCheckingBill.set("outsettlementnum", "");
|
|
|
+
|
|
|
+ //============================航程信息=============================
|
|
|
+ // 航空公司名称
|
|
|
+ planeCheckingBill.set("airlinename", airlineCompanyName);
|
|
|
+ // 电子客票号
|
|
|
+ planeCheckingBill.set("ticketnum", ticketNo);
|
|
|
+ // 航班号
|
|
|
+ planeCheckingBill.set("flightno", flight);
|
|
|
+ // 舱位
|
|
|
+ planeCheckingBill.set("cabin", subClass);
|
|
|
+ // 舱位等级
|
|
|
+ planeCheckingBill.set("cabinclass", cabinClass);
|
|
|
+ // 出发城市名称
|
|
|
+ planeCheckingBill.set("fromcityname", departCityName);
|
|
|
+ // 出发日期
|
|
|
+ planeCheckingBill.set("takeofftime", DateUtil.string2date(takeOffTime, null));
|
|
|
+ // 到达城市名称
|
|
|
+ planeCheckingBill.set("tocityname", arrivalCityName);
|
|
|
+ // 到达时间
|
|
|
+ planeCheckingBill.set("landingtime", DateUtil.string2date(arrivalTime, null));
|
|
|
+ // 改签费
|
|
|
+ planeCheckingBill.set("endorsementamount", rebookQueryFee);
|
|
|
+ // 保险费
|
|
|
+ planeCheckingBill.set("assuranceamount", insuranceFee);
|
|
|
+ // 折扣(%)
|
|
|
+ planeCheckingBill.set("discount", priceRate);
|
|
|
+ // 机票价格
|
|
|
+ planeCheckingBill.set("ticketprice", price);
|
|
|
+ // 民航发展基金/税费
|
|
|
+ planeCheckingBill.set("airportprice", "");
|
|
|
+ // 税费
|
|
|
+ planeCheckingBill.set("tax", orderTax);
|
|
|
+ // 服务费
|
|
|
+ planeCheckingBill.set("servicefee", serviceFee);
|
|
|
+ // 燃油费
|
|
|
+ planeCheckingBill.set("fuelprice", tax);
|
|
|
+ // 退票费
|
|
|
+ planeCheckingBill.set("refundamount", refund);
|
|
|
+ // 其他费用-机票建设费
|
|
|
+ planeCheckingBill.set("otheramount", airportFee);
|
|
|
+
|
|
|
+ // 乘机人工号
|
|
|
+ DynamicObject travelername = queryBosUser(employeeId);
|
|
|
+ // 乘机人姓名
|
|
|
+ String travelernames = ObjectUtils.isEmpty(sourcebookedids) ? "" : sourcebookedids.getString("name");
|
|
|
+ planeCheckingBill.set("sourcetravelerid", travelername);
|
|
|
+ planeCheckingBill.set("travelername", travelernames);
|
|
|
+
|
|
|
+ // 行程单号
|
|
|
+ planeCheckingBill.set("itinerarynum", "");
|
|
|
+ // 填开日期
|
|
|
+ planeCheckingBill.set("itinerarydate", "");
|
|
|
+ // 产品子类型
|
|
|
+ planeCheckingBill.set("productsontype", "");
|
|
|
+ // 票价开票类型
|
|
|
+ planeCheckingBill.set("pricebillingtype", "");
|
|
|
+ // 付款/付款申请单号
|
|
|
+ planeCheckingBill.set("paybillnum", "");
|
|
|
+ // 付款状态
|
|
|
+ planeCheckingBill.set("paybillstatus", "");
|
|
|
+ // 凭证号
|
|
|
+ planeCheckingBill.set("vouchernum", "");
|
|
|
+ // 记账日期
|
|
|
+ planeCheckingBill.set("bookeddatereq", "");
|
|
|
+
|
|
|
+
|
|
|
+ //=============================获取发票=================================
|
|
|
+ List<Map<String, Object>> invoiceResultList = InvoiceApiUtils.getInvoiceResult(settlementNo, rebookingtime);
|
|
|
+ if (CollectionUtils.isEmpty(invoiceResultList)) {
|
|
|
+ log.info("结算单号:" + settlementNo + "未查询到发票数据");
|
|
|
+ }else{
|
|
|
+ for (Map<String, Object> resultInvoiceList : invoiceResultList) {
|
|
|
+ //下载地址
|
|
|
+ planeCheckingBill.set("downloadlink", resultInvoiceList.get("invoiceUrl"));
|
|
|
+ //内部下载地址
|
|
|
+ planeCheckingBill.set("kddownloadlink", resultInvoiceList.get("invoiceUrl"));
|
|
|
+ //发票流水号
|
|
|
+ planeCheckingBill.set("serialno", resultInvoiceList.get("invoiceId"));
|
|
|
+ //发票识别成功
|
|
|
+ planeCheckingBill.set("invoiceidentityflag", true);
|
|
|
+ //发票识别异常信息
|
|
|
+ planeCheckingBill.set("identityerrormsg", "");
|
|
|
+ // 票价开票类型
|
|
|
+ String invoiceTypeCode = resultInvoiceList.get("invoiceType").toString();
|
|
|
+ String invoice = InvoiceTypeEnum.getValueByCode(invoiceTypeCode);
|
|
|
+ planeCheckingBill.set("pricebillingtype", invoice);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ resultLists.add(planeCheckingBill);
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.info("处理单条国内机票结算数据时发生异常,数据内容: " + resultMap, e);
|
|
|
}
|
|
|
- //结算批次号
|
|
|
- planeCheckingBill.set("batchno", accCheckBatchNo);
|
|
|
- //结算子批次号
|
|
|
- planeCheckingBill.set("subbatchno", "");
|
|
|
- //费用承担公司
|
|
|
- planeCheckingBill.set("settlemain", "");
|
|
|
- //费用承担部门
|
|
|
- planeCheckingBill.set("settledept", "");
|
|
|
- //申请人公司
|
|
|
- planeCheckingBill.set("company", "");
|
|
|
- //申请人部门
|
|
|
- planeCheckingBill.set("org", "");
|
|
|
- //项目
|
|
|
- planeCheckingBill.set("std_project", projectNo);
|
|
|
- //成本中心
|
|
|
- planeCheckingBill.set("std_costcenter", "");
|
|
|
- //外部系统结算单号
|
|
|
- planeCheckingBill.set("outsettlementnum", "");
|
|
|
- //火车票车票号
|
|
|
- planeCheckingBill.set("trainticketnum", "");
|
|
|
- //出发城市
|
|
|
- planeCheckingBill.set("departcity", "");
|
|
|
- //出发车站
|
|
|
- planeCheckingBill.set("departaddress", "");
|
|
|
- //到达城市
|
|
|
- planeCheckingBill.set("arrivecity", "");
|
|
|
- //到达车站
|
|
|
- planeCheckingBill.set("arriveaddress", "");
|
|
|
- //出发时间
|
|
|
- planeCheckingBill.set("departtime", "");
|
|
|
- //到达时间
|
|
|
- planeCheckingBill.set("arrivetime", "");
|
|
|
- //乘客
|
|
|
- planeCheckingBill.set("passeger", "");
|
|
|
- //乘客姓名
|
|
|
- planeCheckingBill.set("passegername", "");
|
|
|
- //车次
|
|
|
- planeCheckingBill.set("vendorname", "");
|
|
|
- //席位
|
|
|
- planeCheckingBill.set("trainseat", "");
|
|
|
- //火车票价
|
|
|
- planeCheckingBill.set("ticketprice", "");
|
|
|
- //服务费
|
|
|
- planeCheckingBill.set("servicefee", "");
|
|
|
- //退票费
|
|
|
- planeCheckingBill.set("refundamount", "");
|
|
|
- //保险费
|
|
|
- planeCheckingBill.set("assuranceamount", "");
|
|
|
- //下载地址
|
|
|
- planeCheckingBill.set("downloadlink", "");
|
|
|
- //内部下载地址
|
|
|
- planeCheckingBill.set("kddownloadlink", "");
|
|
|
- //发票流水号
|
|
|
- planeCheckingBill.set("serialno", "");
|
|
|
- //发票识别异常信息
|
|
|
- planeCheckingBill.set("identityerrormsg", "");
|
|
|
- //票价开票类型
|
|
|
- planeCheckingBill.set("pricebillingtype", "");
|
|
|
-
|
|
|
- //控制信息
|
|
|
-// ??????。。
|
|
|
- //可抵扣税额
|
|
|
- planeCheckingBill.set("totaltax", "");
|
|
|
- //已开票
|
|
|
- planeCheckingBill.set("hasinvoice", "");
|
|
|
- //付款/付款申请单号
|
|
|
- planeCheckingBill.set("paybillnum", "");
|
|
|
- //付款状态
|
|
|
- planeCheckingBill.set("paybillstatus", "");
|
|
|
- //凭证号
|
|
|
- planeCheckingBill.set("vouchernum", "");
|
|
|
- //记账日期
|
|
|
- planeCheckingBill.set("bookeddatereq", "");
|
|
|
- //记账日期
|
|
|
- planeCheckingBill.set("bookeddatebu", "");
|
|
|
-
|
|
|
- // 4.保存对象
|
|
|
- SaveServiceHelper.save(new DynamicObject[]{planeCheckingBill});
|
|
|
+
|
|
|
+ return resultLists;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据员工工号查询人员信息
|
|
|
+ *
|
|
|
+ * @param employeeId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private DynamicObject queryBosUser(String employeeId) {
|
|
|
+ if (StringUtils.isBlank(employeeId)) {
|
|
|
+ log.info("未找到工号为:" + employeeId + "的人员信息");
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ QFilter userFilter = new QFilter("number", QCP.equals, employeeId);
|
|
|
+ //查询人员表
|
|
|
+ DynamicObject bosUser = BusinessDataServiceHelper.loadSingle("bos_user", "id,name", userFilter.toArray());
|
|
|
+
|
|
|
+ return bosUser;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 从Map中安全获取字符串值,避免空指针异常
|
|
|
+ *
|
|
|
+ * @param map 数据映射
|
|
|
+ * @param key 键名
|
|
|
+ * @return 字符串值,如果不存在或为null则返回空字符串
|
|
|
+ */
|
|
|
+ private String getStringValue(Map<String, Object> map, String key) {
|
|
|
+ return Optional.ofNullable(map.get(key))
|
|
|
+ .map(Object::toString)
|
|
|
+ .orElse("");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询机票结算单
|
|
|
+ *
|
|
|
+ * @param settlementNo 结算单号
|
|
|
+ * @return 结算单对象
|
|
|
+ */
|
|
|
+ private DynamicObject queryPlaneCheckingBill(Object settlementNo) {
|
|
|
+ QFilter[] trainFilter = new QFilter[]{
|
|
|
+ new QFilter("ordernum", QCP.equals, settlementNo)
|
|
|
+ };
|
|
|
+ return BusinessDataServiceHelper.loadSingle("er_planecheckingbill", trainFilter);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -385,37 +508,37 @@ public class DomesticFlightSettlementTask extends AbstractTask {
|
|
|
String nowDateString = DateUtil.date2str(nowDate, DateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS);
|
|
|
|
|
|
log.info("结算单(国内机票) 同步开始时间:" + syncTime);
|
|
|
-
|
|
|
List<Map<String, Object>> dataList = new ArrayList<>();
|
|
|
- for (int i = 0; i < totalPage; i++) {
|
|
|
+ for (int i = 0; i < TOTAL_PAGE; i++) {
|
|
|
//创建接口业务数据参数
|
|
|
Map<String, Object> data = new HashMap<>();
|
|
|
//结算时间始
|
|
|
- data.put("dateFrom", syncTime);
|
|
|
+ data.put("dateFrom", "1970-01-01 00:00:00");
|
|
|
+// data.put("dateFrom", syncTime);
|
|
|
//结算时间止
|
|
|
data.put("dateTo", nowDateString);
|
|
|
//产品类别 0100 国内机票
|
|
|
- data.put("searchType", "0100");
|
|
|
+ data.put("searchType", DOMESTIC_FLIGHT_PRODUCT_TYPE);
|
|
|
//当前页
|
|
|
data.put("current", i + 1);
|
|
|
//每页条数,最多500条
|
|
|
- data.put("size", size);
|
|
|
+ data.put("size", PAGE_SIZE);
|
|
|
//企业卡号
|
|
|
- data.put("enterpriseNo", "JXWL");
|
|
|
+ data.put("enterpriseNo", ENTERPRISE_NO);
|
|
|
//账单类型 01-现结
|
|
|
- data.put("settlementType", "01");
|
|
|
+// data.put("settlementType", "01");
|
|
|
|
|
|
- Map<String, Object> resp = TripSyncUtils.pushApiCallResult("FCSET_OUTAPI_LiteGetSettlementInfo", Boolean.FALSE, data);
|
|
|
+ Map<String, Object> resp = TripSyncUtils.pushApiCallResult(INTERFACE_NAME, Boolean.FALSE, data);
|
|
|
//报错终止同步,等待下次计划执行
|
|
|
if ((Boolean) resp.get("fail")) {
|
|
|
throw new KDBizException(resp.get("message").toString());
|
|
|
}
|
|
|
Map<String, Object> result = (Map<String, Object>) resp.get("result");
|
|
|
- List<Map<String, Object>> resultDataList = (List<Map<String, Object>>) result.getOrDefault("dataList", Collections.emptyList());
|
|
|
+ List<Map<String, Object>> resultDataList = (List<Map<String, Object>>) result.getOrDefault("settlementInfos", Collections.emptyList());
|
|
|
dataList.addAll(resultDataList);
|
|
|
|
|
|
//当前查询数量小于分页数量时结束循环
|
|
|
- if (resultDataList.size() < size) {
|
|
|
+ if (resultDataList.size() < PAGE_SIZE) {
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
@@ -431,7 +554,7 @@ public class DomesticFlightSettlementTask extends AbstractTask {
|
|
|
//是否全量同步
|
|
|
Boolean isAll = (Boolean) sysCtrlParameter.get("nckd_settlementbillall");
|
|
|
if (isAll) {
|
|
|
- return "1970-01-01 00:00:00";
|
|
|
+ return FULL_SYNC_START_TIME;
|
|
|
}
|
|
|
//增量同步小时 填写整数N,同步N小时前到现在新增或修改的数据,不填默认1小时。
|
|
|
int hours = ObjectUtils.isEmpty(sysCtrlParameter.get("nckd_settlementbillhour")) ? 1 : (Integer) sysCtrlParameter.get("nckd_settlementbillhour");
|