ArriveMasterServiceImpl.java 18.5 KB
package com.tianbo.analysis.service.imp;

import com.tianbo.analysis.dao.*;
import com.tianbo.analysis.model.*;
import com.tianbo.analysis.service.ArriveMasterService;
import com.tianbo.analysis.tools.WaybillTools;
import com.tianbo.analysis.tools.XSDValidateWithXML;
import com.tianbo.util.Date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.annotation.Resource;
import java.io.File;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.*;

@Service
@Slf4j
public class ArriveMasterServiceImpl implements ArriveMasterService {

    @Resource
    PREPAREMASTERMapper preparemasterMapper;

    @Resource
    PREPARESECONDARYMapper preparesecondaryMapper;

    @Resource
    ARRIVEDMASTERMapper arrivedmasterMapper;

    @Resource
    ARRIVEDSECONDARYMapper arrivedsecondaryMapper;

    @Resource
    SENDLOGMapper sendlogMapper;

    @Autowired
    private TemplateEngine templateEngine;

    @Value("${customs.xml-path}")
    private String saveXmlDir;

    @Value("${customs.transport-number}")
    private String transportNo;

    @Override
    public boolean arrivedAhead(AdvanceArrive carAndWayBill) {
        try {
            /**
             * 根据运单列表,与预配核碰提前运抵货物。
             */
            List<LAND_BUSINEESTYPE_LIST_INFO> waybillList = carAndWayBill.getMasterList();
            if (!waybillList.isEmpty()){
                log.info("接收到通知车辆{}拉货数据{}条",carAndWayBill.getVname(),carAndWayBill.getMasterList().size());
                for (LAND_BUSINEESTYPE_LIST_INFO waybillmasterInfo : waybillList) {
                    String waybillmaster = waybillmasterInfo.getAwba();
                    log.info("开始核对运单{}",waybillmaster);
                    /**
                     * 校验运单格式,要为172-66666666,中间有减号的才行
                     * 校验不通过的属于17288888888这种格式的给他加个-号再处理
                     */
                    if (!WaybillTools.checkWaybillFormat(waybillmaster)) {
                        log.info("处理{}运单格式",waybillmaster);
                        waybillmaster = WaybillTools.awbFormat(waybillmaster);
                    }
                    /**
                     * 找提前运抵预配
                     * 这里注意,同一个预配有可能多发,所以有重复。
                     * 这里目前只取回执状态为04以及提前运抵为Y的预配主单
                     */
                    List<PREPAREMASTER> preparemasterList = preparemasterMapper.selectArrivedAheadByWaybillNo(waybillmaster);
                    /**
                     * 判断是否为空
                     * 有多个符合条件的预配只取最新的第一个
                     */
                    if (!preparemasterList.isEmpty()) {
                        PREPAREMASTER preparemasterFirst = preparemasterList.get(0);
                        log.info("查到提前运抵运单:{}", preparemasterFirst.getWaybillnomaster());
                        importFromPreplan(preparemasterFirst);
                    }else {
                        log.info("运单{}不属于提前运抵运单", waybillmaster);
                    }
                }
                return true;
            }
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    @Override
    public boolean importFromPreplan(@NotNull PREPAREMASTER preparemasterFirst) {

        try {
            //共用入库主键
            String id = UUID.randomUUID().toString();
            /**
             * 根据主单号判断是否有预配分单。
             */
            List<PREPARESECONDARY> preparesecondaryList = preparesecondaryMapper.selectByMasterKey(preparemasterFirst.getAutoid());
            /**
             * 根据预配生成运抵数据
             * 生成规则,有运抵数据则不生,无运抵数据才生。
             */
            if (preparesecondaryList.isEmpty()) {
                log.info("运单{}预配没有分单,开始生成主单运抵",preparemasterFirst.getWaybillnomaster());
                /**
                 * 预配没分单,直接生成主单运抵
                 */
                ARRIVEDMASTER arrivedmaster = new ARRIVEDMASTER();
                arrivedmaster.setAutoid(id);
                arrivedmaster.setArrivedAhead("Y");
                arrivedmaster.setTcdName("Air Waybill");
                arrivedmaster.setTcdTypecode("741");
                arrivedmaster.setoName("ZHENGZHOU");
                arrivedmaster.setGrossweightmeasureuc("KGM");
                arrivedmaster.setTotalgrossweightmeasureuc("KGM");
                arrivedmaster.setChargeableweightmeasureuc("KGM");
                arrivedmaster.setTransportsplitdescription("T");
                arrivedmaster.setStatus("01");
                arrivedmaster.setCreatedate(new Date());

                arrivedmaster.setWaybillnomaster(preparemasterFirst.getWaybillnomaster());
                arrivedmaster.setFlightno(preparemasterFirst.getFlightno());
                arrivedmaster.setFlightdate(preparemasterFirst.getFlightdate());
                arrivedmaster.setCarrier(preparemasterFirst.getCarrier());
                arrivedmaster.setOriginatingstation(preparemasterFirst.getOriginatingstation());
                arrivedmaster.setDestinationstation(preparemasterFirst.getDestinationstation());
                arrivedmaster.setArrivedtotalpiece(preparemasterFirst.getTotalpiece());
                arrivedmaster.setTotalpiecequantity(preparemasterFirst.getTotalpiece());
                arrivedmaster.setArrivedtotalweight(preparemasterFirst.getTotalweight());
                arrivedmaster.setTotalgrossweightmeasure(preparemasterFirst.getTotalweight());
                arrivedmaster.setChargeableweightmeasure(preparemasterFirst.getTotalweight());
                arrivedmaster.setArriveddate(new Date());
                arrivedmaster.setCustomscode(preparemasterFirst.getCustomscode());
                arrivedmaster.setProductname(preparemasterFirst.getProductname());

                //查重 根据运单号,有运抵数据则不插入也不更新了,说明已经产生过业务
                List<ARRIVEDMASTER> arrivedmasterList = arrivedmasterMapper.selectByWaybillNo(preparemasterFirst.getWaybillnomaster());
                if (arrivedmasterList.isEmpty()) {
                    int i = arrivedmasterMapper.insertSelective(arrivedmaster);
                    log.info("已插入提前运抵数据:{},运单号为{}", i, arrivedmaster.getWaybillnomaster());
                }else {
                    log.info("运单{}已存在运抵数据,不再提前生成运抵信息",preparemasterFirst.getWaybillnomaster());
                }

            } else {
                //根据分单预配生成分单运抵
                for (PREPARESECONDARY preparesecondary : preparesecondaryList) {
                    log.info("运单{}预配含有分单,生成分单运抵",preparemasterFirst.getWaybillnomaster());
                    String id_slave = UUID.randomUUID().toString();
                    ARRIVEDSECONDARY arrivedsecondary = new ARRIVEDSECONDARY();
                    arrivedsecondary.setAutoid(id_slave);
                    arrivedsecondary.setWaybillnomaster(preparesecondary.getWaybillnomaster());
                    arrivedsecondary.setWaybillnosecondary(preparesecondary.getWaybillnosecondary());
                    arrivedsecondary.setCarrier(preparesecondary.getCarrier());
                    arrivedsecondary.setoId(preparesecondary.getOriginatingstation());
                    arrivedsecondary.setFdId(preparesecondary.getDestinationstation());
                    arrivedsecondary.setFlightno(preparesecondary.getFlightno());
                    arrivedsecondary.setFlightdate(preparesecondary.getFlightdate());
                    arrivedsecondary.setArrivedtotalpiece(preparesecondary.getTotalpiece());
                    arrivedsecondary.setArrivedtotalweight(preparesecondary.getTotalweight());
                    arrivedsecondary.setTotalpiecequantity(preparesecondary.getTotalpiece());
                    arrivedsecondary.setTotalgrossweightmeasure(preparesecondary.getTotalweight());
                    arrivedsecondary.setChargeableweightmeasure(preparesecondary.getTotalweight());
                    arrivedsecondary.setArriveddate(new Date());
                    arrivedsecondary.setCustomscode(preparesecondary.getCustomscode());
                    arrivedsecondary.setProductname(preparesecondary.getProductname());
                    arrivedsecondary.setCreatedate(new Date());
                    arrivedsecondary.setArrivedmasterid("");
                    arrivedsecondary.setStatus("01");

                    arrivedsecondary.setTcdName("Air Waybill");
                    arrivedsecondary.setTcdTypecode("741");
                    arrivedsecondary.setoName("ZHENGZHOU");

                    //查重 根据运单号,有运抵数据则不插入也不更新了,说明已经产生过业务
                    List<ARRIVEDSECONDARY> arrivedsecondaryList = arrivedsecondaryMapper.selectByWaybillNo(arrivedsecondary);
                    if (arrivedsecondaryList.isEmpty()) {
                        int i = arrivedsecondaryMapper.insertSelective(arrivedsecondary);
                        log.info("已插入提前运抵数据,插入数量:{},运单号为{}_{}", i, arrivedsecondary.getWaybillnomaster(), arrivedsecondary.getWaybillnosecondary());

                        /**
                         * 插入日志。
                         */
                        if (i > 0) {
                            SENDLOG sendlog = new SENDLOG();
                            sendlog.setAutoid(id_slave);
                            sendlog.setCreatedate(new Date());
                            sendlog.setMessageautoid(id_slave);
                            sendlog.setOpauthor("提前运抵");
                            sendlog.setSendpeice(Long.parseLong(preparesecondary.getTotalpiece()));
                            sendlog.setSendweight(new BigDecimal(preparesecondary.getTotalweight()));
                            sendlog.setReceiption("SYSTEM 提前运抵生成");
                            sendlog.setMessagetype("MT3201");
                            sendlogMapper.insertSelective(sendlog);
                            log.info("分单生成日志已记录");
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }

    @Override
    public int updatePremasterArrivedHeadStatus(AdvanceArrive preArrivedWaybillList) {
        log.info("接收到来自卡口申请的拉货列表通知");
        if (!preArrivedWaybillList.getMasterList().isEmpty()){
            int m = 0;
            for (LAND_BUSINEESTYPE_LIST_INFO waybillnomaster: preArrivedWaybillList.getMasterList() ) {
                String waybillNo = waybillnomaster.getAwba();
                log.info("开始处理列表中的运单号:[{}]",waybillNo);
                if ("1".equals(waybillnomaster.getArrivedaheadtime())){
                    log.info("运单号{}识别为提前运抵业务,即将增加数据标识",waybillNo);
                    PREPAREMASTER  preparemaster = new PREPAREMASTER();
                    preparemaster.setWaybillnomaster(waybillNo);
                    preparemaster.setArrivedAhead("Y");
                    int i = preparemasterMapper.updatePreArrivedBill(preparemaster);
                    if (i > 0) {
                        log.info("运单号{}的预配提前运抵标识增加成功", waybillNo);
                    } else {
                        log.info("ERROR :未找到相关预配信息,  运单号{}的预配提前运抵标识增加失败!!!", waybillNo);
                    }
                    m =+ i;
                }

            }

            return m;
        }
        return 0;
    }

    @Override
    public boolean checkSender(String wayBillno) {
        return false;
    }

    @Override
    public boolean batchDel(BatchSend batchSend, String username) {
        CustomsHead customsHead = new CustomsHead();
        String nowStr = DateUtil.getCurrentTime17();
        String messageID = "CN_"
                + "MT3201"
                + "_1P0_"
                + transportNo+
                "_" + nowStr;

        customsHead.setMessageId(messageID);
        customsHead.setSendTime(nowStr);

        //航班信息存储
        HashMap<String, String> flightMap = new HashMap<>();
        ArrayList<Map> bills = new ArrayList<>();


        /**
         * noList: master;fc68f797-58f9-4276-850d-f772ab54e041;Y87489;2018/7/16 0:00:00;871-52149624;NO;4620
         * noList: sub;e430bacf-d34d-49c4-a646-c6bab53245d9;Y87489;2018/7/16 0:00:00;871-52149624;5758599033;4620
         * noList: sub;4ff7853f-0315-4632-ad0f-6a028054513d;Y87489;2018/7/16 0:00:00;871-52149624;5758599022;4620
         * noList: sub;52dc1407-d686-42ac-87cd-ddacdb84ca18;Y87489;2018/7/16 0:00:00;871-52149624;5758599044;4620
         * noList: sub;26bf643c-cf5b-4af2-8394-51585c02d88d;Y87489;2018/7/16 0:00:00;871-52149624;5758599077;4620
         */
        if (batchSend.billListDes!=null && !batchSend.billListDes.isEmpty() && batchSend.businessAlterLog!=null){
            for (String item : batchSend.billListDes) {
                HashMap<String, String> billsMap = new HashMap<>();
                String[] split = item.split(";");
                //单证类别:master为主单,sub为分单
                String billType = split[0];
                String billAutoId = split[1];
                //航班号
                String flightNo = split[2];
                //航班日期
                String flightDateString = split[3];
                // 主单号
                String billMasterNo = split[4].replace("-","");
                // 分单号
                String billSecNo = split[5];
                // 申报关区
                String customCode = split[6];

                flightMap.put("flightNo",flightNo);
                flightMap.put("flightDate",flightDateString);
                //设置关区
                customsHead.setReceiverID(customCode);

                billsMap.put("billAutoId",billAutoId);
                billsMap.put("billMasterNo",billMasterNo);
                billsMap.put("billSecNo",billMasterNo +"_" +billSecNo);
                billsMap.put("billType",billType);
                bills.add(billsMap);
            }
        }

        Context context = new Context();
        context.setVariable("bills",bills);
        context.setVariable("head",customsHead);
        context.setVariable("flight",flightMap);
        context.setVariable("reason",batchSend.businessAlterLog);
        context.setLocale(Locale.SIMPLIFIED_CHINESE);

        //生成的文件名
        String fileName = messageID + ".xml";
        //生成的报文路径,带斜杠
        String filePath = saveXmlDir+fileName;
        try {
            File file = ResourceUtils.getFile(filePath);
            /**
             * 中文的地方在模板中要用utext,否则中文会被 escape 转义
             */
            String xmlStr = templateEngine.process("mt3201/MT3201_D.xml",context);
            System.out.println("xmlStr = " + xmlStr);
            boolean valied =  XSDValidateWithXML.validateXMLSchema("xsd/Manifest_Arrival_Air_Delete_3201_3.xsd",xmlStr);

            if (valied){
                // 生成报文
                FileUtils.writeStringToFile(file,xmlStr, StandardCharsets.UTF_8);
                log.info("[PRE-BATCH-SEND]-SUCCESS,批量删除发送成功");

                // 更新运单状态,含主单表和分单表
                Boolean b = updateBatchStatus(batchSend, bills, username);
                return b;
            }else {
                return false;
            }
        } catch (Exception e) {
            log.error("[PRE-BATCH-DEL]-批量删除发生异常,{}",e.getMessage());
            return false;
        }
    }

    private Boolean updateBatchStatus(BatchSend batchSend,ArrayList<Map> bills,String username) {
        //存储更新主单状态的列表
        ArrayList<ARRIVEDMASTER> masters = new ArrayList<>();
        ArrayList<ARRIVEDSECONDARY> subs = new ArrayList<>();
        List<SENDLOG> sendlogList = new ArrayList<>();

        for (Map<String,String> item : bills) {
            // 批量插入发送日志
            SENDLOG sendlog = new SENDLOG();
            sendlog.setAutoid(UUID.randomUUID().toString());
            sendlog.setMessageautoid(item.get("billAutoId"));
            sendlog.setMessagetype(batchSend.businessAlterLog.getBusinesstype());
            sendlog.setCreatedate(new Date());
            sendlog.setReceiption("新舱单系统发送运抵舱单批量删除报");
            sendlog.setOpauthor(username);
            sendlog.setSendpeice(new Long(0));
            sendlog.setSendweight(new BigDecimal(0));
            sendlogList.add(sendlog);

            if ("master".equals(item.get("billType"))){
                ARRIVEDMASTER master = new ARRIVEDMASTER();
                master.setAutoid(item.get("billAutoId"));
                masters.add(master);
            }else {
                ARRIVEDSECONDARY scondary = new ARRIVEDSECONDARY();
                scondary.setAutoid(item.get("billAutoId"));
                subs.add(scondary);
            }
        }
        int i = sendlogMapper.batchInsert(sendlogList);
        if (i>0){
            log.info("[PRE-BATCH-DEL-LOG-INSERT]-SUCCESS");
        }else {
            log.error("[PRE-BATCH-DEL-LOG-INSERT]-FAILD");
            return false;
        }

        /**
         * 以下两个批量更新语句无法返回具体影响行数,返回为-1
         * 要么得配置在mybatis-config.xml,如下
         * <configuration>
         *     <settings>
         *         <setting name="defaultExecutorType" value="SIMPLE"/>
         *         <setting name="defaultExecutorType" value="BATCH"/>
         *     </settings>
         * </configuration>
         */

        int i1 = arrivedmasterMapper.updateDelStatusByPrimaryKey(masters);
        int i2 = arrivedsecondaryMapper.updateDelStatusByPrimaryKey(subs);

        return true;
    }
}