ErpCallbackService.java 8.15 KB
package com.huaheng.api.erp.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.huaheng.api.erp.domain.PurchaseDeliveryCreateRequest;
import com.huaheng.api.erp.domain.PurchaseDeliveryCreateResponse;
import com.huaheng.common.constant.QuantityConstant;
import com.huaheng.common.utils.DateUtils;
import com.huaheng.common.utils.StringUtils;
import com.huaheng.common.utils.restful.RestUtil;
import com.huaheng.common.utils.security.ShiroUtils;
import com.huaheng.framework.web.domain.AjaxResult;
import com.huaheng.pc.config.address.service.AddressService;
import com.huaheng.pc.receipt.receiptDetail.domain.ReceiptDetail;
import com.huaheng.pc.receipt.receiptHeader.domain.ReceiptHeader;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * ERP回调服务。
 */
@Service
public class ErpCallbackService {

    private static final String DEFAULT_PMD_S000 = "6";

    @Resource
    private AddressService addressService;

    /**
     * WMS上架完成后,通知ERP产生采购入库单。
     *
     * @param receiptHeader  入库单头
     * @param receiptDetails 入库单明细
     * @return ERP响应结果
     */
    public AjaxResult<PurchaseDeliveryCreateResponse> createPurchaseDelivery(ReceiptHeader receiptHeader,
                                                                             List<ReceiptDetail> receiptDetails) {
        if (receiptHeader == null) {
            return AjaxResult.error("入库单头不能为空");
        }
        if (StringUtils.isEmpty(receiptDetails)) {
            return AjaxResult.error("入库单明细不能为空");
        }

        PurchaseDeliveryCreateRequest request = buildPurchaseDeliveryCreateRequest(receiptHeader, receiptDetails);
        String jsonParam = JSON.toJSONString(request);

        try {
            String url = addressService.selectAddress(QuantityConstant.ADDRESS_ERP_CALLBACK,
                    QuantityConstant.DEFAULT_WAREHOUSE, QuantityConstant.DEFAULT_AREA);
            ResponseEntity<JSONObject> result = RestUtil.request_post(url, QuantityConstant.DEFAULT_WAREHOUSE, jsonParam);

            if (result == null || result.getBody() == null) {
                return AjaxResult.error("调用ERP采购入库单接口失败,接口地址错误或返回为空");
            }

            PurchaseDeliveryCreateResponse response = JSONObject.parseObject(result.getBody().toString(),
                    PurchaseDeliveryCreateResponse.class);
            if (response == null) {
                return AjaxResult.error("调用ERP采购入库单接口失败,响应解析为空");
            }
            if (!isErpSuccess(response)) {
                return AjaxResult.error(getErpErrorMessage(response), response);
            }
            return AjaxResult.success("调用ERP采购入库单接口成功", response);
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 封装ERP采购入库单创建请求。
     */
    private PurchaseDeliveryCreateRequest buildPurchaseDeliveryCreateRequest(ReceiptHeader receiptHeader,
                                                                            List<ReceiptDetail> receiptDetails) {
        PurchaseDeliveryCreateRequest request = new PurchaseDeliveryCreateRequest();

        request.getHost().setIp(getClientIp());

        request.getService().setAcct(getServiceAcct(receiptHeader));
        request.getService().setTimestamp(new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()));
        request.getService().setId(PurchaseDeliveryCreateRequest.SERVICE_ID_PROD);

        request.getDatakey().setEntId(receiptHeader.getCompanyCode());
        request.getDatakey().setCompanyId(receiptHeader.getWarehouseCode());

        PurchaseDeliveryCreateRequest.Master master = request.getDatakey().getMaster();
        master.setPmdsdocno(receiptHeader.getReceiptType());
        master.setPmdsdocdt(formatDate(receiptHeader.getOrderDate(), new Date()));
        master.setPmds000(defaultIfBlank(receiptHeader.getUserDef1(), DEFAULT_PMD_S000));
        master.setPmds006(defaultIfBlank(receiptHeader.getReferCode(), receiptHeader.getPo()));
        master.setPmds002(defaultIfBlank(receiptHeader.getMakerName(), receiptHeader.getCreatedBy()));
        master.setPmds007(receiptHeader.getSupplierCode());
        master.setSourceNo(receiptHeader.getCode());
        master.setDetail(buildDetails(receiptHeader, receiptDetails));

        return request;
    }

    /**
     * 封装ERP采购入库单明细。
     */
    private List<PurchaseDeliveryCreateRequest.Detail> buildDetails(ReceiptHeader receiptHeader,
                                                                    List<ReceiptDetail> receiptDetails) {
        List<PurchaseDeliveryCreateRequest.Detail> details = new ArrayList<>();
        for (int i = 0; i < receiptDetails.size(); i++) {
            ReceiptDetail receiptDetail = receiptDetails.get(i);
            PurchaseDeliveryCreateRequest.Detail detail = new PurchaseDeliveryCreateRequest.Detail();

            detail.setPmdt027(defaultIfBlank(receiptDetail.getReferCode(), receiptHeader.getReferCode()));
            detail.setPmdt028(toBigDecimal(receiptDetail.getReferLineNum(), i + 1));
            detail.setPmdt006(receiptDetail.getMaterialCode());
            detail.setPmdt007(receiptDetail.getUserDef1());
            detail.setPmdt019(receiptDetail.getMaterialUnit());
            detail.setPmdt020(receiptDetail.getQty());
            detail.setPmdt016(defaultIfBlank(receiptDetail.getAreaCode(), receiptDetail.getWarehouseCode()));
            detail.setPmdt017(receiptDetail.getUserDef2());
            detail.setPmdt018(defaultIfBlank(receiptDetail.getLot(), receiptDetail.getBatch()));
            detail.setSourceSeq(defaultIfBlank(receiptDetail.getReferLineNum(), String.valueOf(i + 1)));

            details.add(detail);
        }
        return details;
    }

    /**
     * 判断ERP是否执行成功。
     */
    private boolean isErpSuccess(PurchaseDeliveryCreateResponse response) {
        return "0".equals(response.getCode())
                && (StringUtils.isEmpty(response.getSrvcode()) || "000".equals(response.getSrvcode()))
                && (response.getFailnum() == null || BigDecimal.ZERO.compareTo(response.getFailnum()) == 0);
    }

    /**
     * 获取ERP错误信息。
     */
    private String getErpErrorMessage(PurchaseDeliveryCreateResponse response) {
        if (StringUtils.isNotEmpty(response.getDescription())) {
            return response.getDescription();
        }
        if (StringUtils.isNotEmpty(response.getCode())) {
            return "ERP返回错误码:" + response.getCode();
        }
        return "调用ERP采购入库单接口失败";
    }

    /**
     * 获取服务用户编号。
     */
    private String getServiceAcct(ReceiptHeader receiptHeader) {
        if (StringUtils.isNotEmpty(receiptHeader.getCreatedBy())) {
            return receiptHeader.getCreatedBy();
        }
        return ShiroUtils.getLoginName();
    }

    /**
     * 获取客户端IP。
     */
    private String getClientIp() {
        try {
            return ShiroUtils.getIp();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 格式化日期。
     */
    private String formatDate(Date date, Date defaultDate) {
        return DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, date == null ? defaultDate : date);
    }

    /**
     * 字符串为空时使用默认值。
     */
    private String defaultIfBlank(String value, String defaultValue) {
        return StringUtils.isEmpty(value) ? defaultValue : value;
    }

    /**
     * 转换为ERP数字字段。
     */
    private BigDecimal toBigDecimal(String value, int defaultValue) {
        if (StringUtils.isEmpty(value)) {
            return BigDecimal.valueOf(defaultValue);
        }
        try {
            return new BigDecimal(value);
        } catch (NumberFormatException e) {
            return BigDecimal.valueOf(defaultValue);
        }
    }
}