package com.yem.wm.es.salesorder.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yem.em.utils.BigDecimalUtils;
import com.yem.wm.utils.DynamicObjectUtil;
import com.yem.wm.utils.RequestCmmp;
import com.yem.wm.utils.RequestEAS;
import com.yem.wm.utils.YEM;
import kd.bos.bill.BillShowParameter;
import kd.bos.bill.OperationStatus;
import kd.bos.cache.CacheFactory;
import kd.bos.cache.TempFileCache;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.datamodel.IDataModel;
import kd.bos.entity.operate.result.IOperateInfo;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.exception.KDBizException;
import kd.bos.fileservice.FileItem;
import kd.bos.fileservice.FileService;
import kd.bos.fileservice.FileServiceFactory;
import kd.bos.form.IFormView;
import kd.bos.form.ShowType;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.util.FileNameUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;

import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.yem.wm.im.tracktaskconsole.form.tracktaskconsoleFormPlugIn.gettolreqqty;

/**
 * 外销合同工具类
 */
public class SalesOrderUtils {

    /**
     * 外销合同取消下单逻辑：只有下单审批不等于审批中、已审核，就可以进行取消下单任务
     *
     * @param rows
     * @param bill
     */
    public static void revokeplan_placeexamine(int[] rows, DynamicObject bill) {
        if (null == rows || rows.length == 0) {
            throw new KDBizException("请先选择取消行！");
        }
        List del_id_s = new ArrayList();
        DynamicObjectCollection yem_shippingplan_entry_s = bill.getDynamicObjectCollection("yem_shippingplan_entry");
        Map map = new HashMap<>();
        for (int i = 0; i < rows.length; i++) {
            DynamicObject yem_shippingplan_entry = yem_shippingplan_entry_s.get(rows[i]);
            DynamicObject yemPlaceexamine = yem_shippingplan_entry.getDynamicObject("yem_placeexamine");
            if (yemPlaceexamine != null) {
                if (!map.containsKey(yemPlaceexamine.getLong("id"))) {
                    map.put(yemPlaceexamine.getLong("id"), yemPlaceexamine);
                }
            }
            //下单审批
            Iterator iterator = map.keySet().iterator();
            while (iterator.hasNext()) {
                String key = iterator.next().toString();
                DynamicObject yem_tracktaskconsole = BusinessDataServiceHelper.loadSingle(key, "yem_placeexamine");
                String billstatus = yem_tracktaskconsole.getString("billstatus");
                if (!"A".equals(billstatus)) {
                    throw new KDBizException("第" + (rows[i] + 1) + "行下单审批已提交/审核，不允许取消！");
                }
                del_id_s.add(yem_tracktaskconsole.getLong("id"));
            }
        }
        //删除下单审批
        if (del_id_s.size() > 0) {
//            QFilter qFilter = new QFilter("id", QCP.in, del_id_s);
//            DeleteServiceHelper("yem_placeexamine", new QFilter[]{qFilter});
            for (int i = 0; i < del_id_s.size(); i++) {
                Object o = del_id_s.get(i);
                OperationResult delete = OperationServiceHelper.executeOperate("delete", "yem_placeexamine", new Object[]{o}, OperateOption.create());
                if (!delete.isSuccess()) {
                    String message = delete.getMessage();
                    List<IOperateInfo> allErrorOrValidateInfo = delete.getAllErrorOrValidateInfo();
                    throw new KDBizException(String.format("《下单审批》删除失败，%s，%s", message, allErrorOrValidateInfo));
                }
            }
        }

        for (int i = rows.length - 1; i >= 0; i--) {
            yem_shippingplan_entry_s.remove(rows[i]);
        }
        cal_yem_orderqty(bill);
        SaveServiceHelper.save(new DynamicObject[]{bill});
    }

    /**
     * 计算已下单数量、剩余未下单数量
     *
     * @param bill 外销合同
     */
    public static void cal_yem_orderqty(DynamicObject bill) {
        Map map = new HashMap();
        DynamicObjectCollection yem_shippingplan_entry_s = bill.getDynamicObjectCollection("yem_shippingplan_entry");
        for (int i = 0; i < yem_shippingplan_entry_s.size(); i++) {
            DynamicObject yem_shippingplan_entry = yem_shippingplan_entry_s.get(i);
            DynamicObjectCollection yem_plandetail_entry_s = yem_shippingplan_entry.getDynamicObjectCollection("yem_plandetail_entry");
            for (int j = 0; j < yem_plandetail_entry_s.size(); j++) {
                DynamicObject yem_plandetail_entry = yem_plandetail_entry_s.get(j);
                BigDecimal yem_qty2 = yem_plandetail_entry.getBigDecimal("yem_qty2");
                long yem_srcentryid = yem_plandetail_entry.getLong("yem_srcentryid");
                if (map.containsKey(yem_srcentryid)) {
                    BigDecimal yem_qty2_old = new BigDecimal(map.get(yem_srcentryid).toString());
                    map.put(yem_srcentryid, yem_qty2_old.add(yem_qty2));
                } else {
                    map.put(yem_srcentryid, yem_qty2);
                }
            }
        }
        DynamicObjectCollection yem_es_materialinfo_s = bill.getDynamicObjectCollection("yem_es_materialinfo");
        for (int i = 0; i < yem_es_materialinfo_s.size(); i++) {
            DynamicObject yem_es_materialinfo = yem_es_materialinfo_s.get(i);
            BigDecimal yem_qty = yem_es_materialinfo.getBigDecimal("yem_qty");
            BigDecimal yem_orderqty = BigDecimalUtils.toBigDecimal(map.get(yem_es_materialinfo.getLong("id")));
            BigDecimal yem_unorderqty = BigDecimalUtils.sub(yem_qty, yem_orderqty, 10);
            yem_es_materialinfo.set("yem_orderqty", yem_orderqty);
            yem_es_materialinfo.set("yem_unorderqty", yem_unorderqty);
        }
    }

    /**
     * 打开单据
     *
     * @param okid   单据id
     * @param Formid 单据标识
     */
    public static void OpenFrom(IFormView view, Object okid, String Formid) {
        BillShowParameter parameter = new BillShowParameter();//跳转指定单据
        parameter.setPkId(okid);
        parameter.getOpenStyle().setShowType(ShowType.MainNewTabPage);
        parameter.setFormId(Formid);
        parameter.setStatus(OperationStatus.EDIT);
        view.showForm(parameter);
    }

    /**
     * 配件客商额度申请 计算已用额度 | 剩余额度
     *
     * @param id 配件客商额度申请单实体
     */
    public static void calcCreditAmount(long id) {
        DynamicObject object = BusinessDataServiceHelper.loadSingle(id, "yem_im_partsmerchant");

        // 客户额度
        BigDecimal amount = object.getBigDecimal("yem_amount");

        // 计算已用额度
        BigDecimal calcReplylimit = BigDecimal.ZERO;
        // 计算剩余额度
        BigDecimal calcBalance;
        DynamicObjectCollection collection = object.getDynamicObjectCollection("yem_im_entryentity_m");
        for (DynamicObject item : collection) {

            long contractId = item.getLong("yem_cn.id");

            if (contractId == 0) {
                continue;
            }

            // 合同占用金额
            BigDecimal usedAmount = item.getBigDecimal("yem_sum");

            // 核销金额
            BigDecimal writtenamt = item.getBigDecimal("yem_writtenamt");

            calcReplylimit = calcReplylimit.add(usedAmount).subtract(writtenamt);
        }
        calcBalance = amount.subtract(calcReplylimit);
        object.set("yem_replylimit", calcReplylimit);
        object.set("yem_balance", calcBalance);
        SaveServiceHelper.update(new DynamicObject[]{object});
    }

    // 附件持久化
    public static String uploadTempfile(String url, String name) {
        TempFileCache cache = CacheFactory.getCommonCacheFactory().getTempFileCache();
        InputStream in = cache.getInputStream(url);
        FileService service = FileServiceFactory.getAttachmentFileService();
        RequestContext requestContext = RequestContext.get();
        String uuid = UUID.randomUUID().toString().replace("-", "");
        // 生成文件路径-上传附件时远程服务器需要存储文件的位置
        String pathParam = FileNameUtils.getAttachmentFileName(requestContext.getTenantId(),
                requestContext.getAccountId(), uuid, name);
        FileItem fileItem = new FileItem(name, pathParam, in);
        // 上传附件到文件服务器
        return service.upload(fileItem);
    }


    /**
     * 根据编码规则设置合同号(框架合同)
     *
     * @param input
     * @return
     */
    public static String replaceSerialNumberWithLetters(String input, String formId) {

        if (input.isEmpty()) {
            return input;
        }
        int lastIndex = input.lastIndexOf("-");

        if (lastIndex < 0) {
            return input;
        }

        String billnoSer = input.substring(lastIndex + 1);

        if (isLetter(billnoSer)) {
            return input;
        }

        String billnoNoSer = input.substring(0, lastIndex);

        QFilter qFilter = new QFilter("billno", QCP.like, billnoNoSer + "%");
        DynamicObject[] load = BusinessDataServiceHelper.load(formId, "id, billno", qFilter.toArray());

        ArrayList<String> billnos = new ArrayList<>();
        for (DynamicObject dynamicObject : load) {
            String billno = dynamicObject.getString("billno");

            String serNumber = getSerNumber(billno);
            if (isLetter(serNumber)) {
                billnos.add(serNumber);
            }
        }

        String missingLetter = findMissingLetter(billnos);

        // 将转换后的字母替换原来的数字流水号
        return billnoNoSer + "-" + missingLetter;
    }

    public static String findMissingLetter(ArrayList<String> billnos) {
        String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        for (int i = 0; i < alphabet.length(); i++) {
            String letter = String.valueOf(alphabet.charAt(i));
            if (!billnos.contains(letter)) {
                return letter;
            }
        }
        return "(ERROR)";
    }

    public static String getSerNumber(String input) {
        // 使用正则表达式匹配最后一个破折号后的流水号
        String[] parts = input.split("-");
        return parts[parts.length - 1];
    }

    public static boolean isLetter(String str) {
        if (str.length() != 1) {
            return false;
        }
        char ch = str.charAt(0);
        return Character.isLetter(ch);
    }

    /**
     * 根据贸易国别和运输方式匹配基础资料运保费率中的数据；
     */
    public static void carryPriceItem(IDataModel model, IFormView view) {
        DynamicObject dataEntity = model.getDataEntity(true);
        // 价格条款
        DynamicObject priceitem = dataEntity.getDynamicObject("yem_priceitem");
        // 贸易国别
        long clientcountry = dataEntity.getLong("yem_clientcountry.id");
        // 运输方式
        long transportstyle = dataEntity.getLong("yem_transportstyle.id");
        if (priceitem == null) {
            model.setValue("yem_insurancefeerate", BigDecimal.ZERO);
            model.setValue("yem_insuranceaddrate", BigDecimal.ZERO);
            view.updateView("yem_insurancefeerate");
            return;
        }
        String name = priceitem.getString("name");
        QFilter qFilter = null;
        if ("CIF".equals(name)) {

            if (YEM.isNotEmpty(transportstyle)) {
                qFilter = new QFilter("yem_rateinfo.yem_transway.id", QCP.in, transportstyle);
            }

            if (YEM.isNotEmpty(priceitem) && YEM.isNotEmpty(qFilter)) {
                DynamicObject[] load = BusinessDataServiceHelper.load("yem_bd_rate", "id, billno, yem_rateinfo.yem_transway, yem_rateinfo.yem_country, yem_rateinfo.yem_rate", qFilter.toArray());

                Map<String, Map<String, Object>> map = new LinkedHashMap<>();
                for (DynamicObject dynamicObject : load) {
                    DynamicObjectCollection collection = dynamicObject.getDynamicObjectCollection("yem_rateinfo");
                    for (DynamicObject object : collection) {
                        Map<String, Object> subMap = new LinkedHashMap<>();
                        long transway = object.getLong("yem_transway.id");
                        long country = object.getLong("yem_country.id");
                        BigDecimal rate = object.getBigDecimal("yem_rate");
                        subMap.put("rate", rate);

                        map.put(transway + "-" + country, subMap);
                    }
                }

                Set<Map.Entry<String, Map<String, Object>>> entries = map.entrySet();

                for (Map.Entry<String, Map<String, Object>> entry : entries) {
                    String key = entry.getKey();
                    Map<String, Object> value = entry.getValue();
                    String[] split = key.split("-");
                    long transwayId = Long.parseLong(split[0]);
                    long countryId = Long.parseLong(split[1]);

                    if (transportstyle == transwayId && clientcountry == countryId) {
                        BigDecimal rate = (BigDecimal) value.get("rate");
                        model.setValue("yem_insurancefeerate", rate);
                        model.setValue("yem_insuranceaddrate", new BigDecimal("1.1"));
                        view.updateView("yem_insurancefeerate");
                        return;
                    }
                }

                for (Map.Entry<String, Map<String, Object>> entry : entries) {
                    String key = entry.getKey();
                    Map<String, Object> value = entry.getValue();
                    String[] split = key.split("-");
                    long transwayId = Long.parseLong(split[0]);
                    long countryId = Long.parseLong(split[1]);

                    if (transportstyle == transwayId && 0 == countryId) {
                        BigDecimal rate = (BigDecimal) value.get("rate");
                        model.setValue("yem_insurancefeerate", rate);
                        model.setValue("yem_insuranceaddrate", new BigDecimal("1.1"));
                        view.updateView("yem_insurancefeerate");
                        return;
                    }
                }
            }
        }

        model.setValue("yem_insurancefeerate", BigDecimal.ZERO);
        model.setValue("yem_insuranceaddrate", BigDecimal.ZERO);
        view.updateView("yem_insurancefeerate");
    }

    /**
     * 信保费率赋值
     *
     * @param model
     * @param view
     */
    public static void setSinosureRate(IDataModel model, IFormView view) {
        DynamicObject commCountry = (DynamicObject) model.getValue("yem_clientcountry");
        int entryRowCount = model.getEntryCurrentRowIndex("yem_es_salescontrac_s");
        DynamicObject dataEntity = model.getDataEntity(true);
        // 是否信保合同
        boolean issinosurecon = dataEntity.getBoolean("yem_issinosurecon");
        DynamicObjectCollection salescontracS = dataEntity.getDynamicObjectCollection("yem_es_salescontrac_s");
        if (salescontracS.isEmpty()) return;
        DynamicObject salescontrac = salescontracS.get(entryRowCount);
        if (YEM.isEmpty(commCountry)) return;
        if (!issinosurecon) {
            model.setValue("yem_sinosurerate", null, entryRowCount);
            view.updateView();
            return;
        }
        ;
        Long pkValue = (Long) commCountry.getPkValue();
        QFilter qFilter = new QFilter("yem_countryinfo.yem_nation.id", QCP.equals, pkValue);
        DynamicObject[] load = BusinessDataServiceHelper.load("yem_bd_signals", "id, billno, yem_countryinfo.yem_nation", qFilter.toArray());
        if (YEM.isEmpty(load)) return;
        // 结算方式
        DynamicObject rapstyle = salescontrac.getDynamicObject("yem_rapstyle");
        // 信用期限
        DynamicObject term = salescontrac.getDynamicObject("yem_term");
        if (YEM.isEmpty(rapstyle) || YEM.isEmpty(term)) return;
        for (DynamicObject dynamicObject : load) {
            dynamicObject = BusinessDataServiceHelper.loadSingle(dynamicObject.getLong("id"), "yem_bd_signals");
            DynamicObjectCollection collection = dynamicObject.getDynamicObjectCollection("yem_bd_signals_em");
            for (DynamicObject object : collection) {
                DynamicObject payment = object.getDynamicObject("yem_payment");
                DynamicObject yem_term = object.getDynamicObject("yem_term");
                if (YEM.isEmpty(payment) || YEM.isEmpty(yem_term)) continue;
                if (rapstyle.getLong("id") == payment.getLong("id") && term.getLong("id") == yem_term.getLong("id")) {
                    model.setValue("yem_sinosurerate", object.getBigDecimal("yem_rate"), entryRowCount);
                    return;
                }
            }
        }
        model.setValue("yem_sinosurerate", null, entryRowCount);
    }

    public static void setNewpPrice(DynamicObject dataEntitie, IFormView view) {
        DynamicObject billType = dataEntitie.getDynamicObject("yem_billtype");
        String billTypeNum = YEM.isNotEmpty(billType) ? billType.getString("number") : "";
        if ("yem_es_salesorder_PJ".equals(billTypeNum) || "yem_es_salesorder_nmpj".equals(billTypeNum)) {
            List<Long> materielId = new ArrayList();
            DynamicObjectCollection materialInfos = dataEntitie.getDynamicObjectCollection("yem_es_materialinfo");
            for (DynamicObject materialInfo : materialInfos) {
                DynamicObject materiel = materialInfo.getDynamicObject("yem_materiel");
                if (YEM.isNotEmpty(materiel)) {
                    materielId.add(materiel.getLong("id"));
                }
            }
            String selectFields = DynamicObjectUtil.getSelectfields("yem_pricelibrary", false);
            selectFields = DynamicObjectUtil.getEntrySelectfields(selectFields, "yem_pricelibrary", "yem_accessory", false);
            DynamicObject[] accPriceLibrarys = BusinessDataServiceHelper.load("yem_pricelibrary", selectFields,
                    new QFilter[]{new QFilter("yem_accessory.yem_material", QCP.in, materielId),
                            new QFilter("billstatus", QCP.equals, "C")});
            for (DynamicObject accPriceLibrary : accPriceLibrarys) {
                Map<Long, Map<String, Object>> allMap = new HashMap<>();
                Date bizDate = accPriceLibrary.getDate("yem_bizdate");
                DynamicObjectCollection accessorys = accPriceLibrary.getDynamicObjectCollection("yem_accessory");
                for (DynamicObject accessory : accessorys) {
                    DynamicObject material = accessory.getDynamicObject("yem_material");
                    if (YEM.isNotEmpty(material)) {
                        BigDecimal standSalesPrice = accessory.getBigDecimal("yem_standsalesprice");
                        long materialId = material.getLong("id");
                        if (allMap.containsKey(materialId)) {
                            Map<String, Object> valueMap = allMap.get(materialId);
                            Date date = (Date) valueMap.get("date");
                            if (bizDate.compareTo(date) > 0) {
                                valueMap.put("price", standSalesPrice);
                                valueMap.put("date", bizDate);
                            }
                        } else {
                            Map<String, Object> valueMap = new HashMap();
                            valueMap.put("price", standSalesPrice);
                            valueMap.put("date", bizDate);
                            allMap.put(materialId, valueMap);
                        }
                    }
                }
                BigDecimal exRate = dataEntitie.getBigDecimal("yem_exrate");
                for (DynamicObject materialInfo : materialInfos) {
                    DynamicObject materiel = materialInfo.getDynamicObject("yem_materiel");
                    if (YEM.isNotEmpty(materiel)) {
                        long materialId = materiel.getLong("id");
                        if (allMap.containsKey(materialId)) {
                            Map<String, Object> valueMap = allMap.get(materialId);
                            BigDecimal price = (BigDecimal) valueMap.get("price");
                            BigDecimal saFobPrice = materialInfo.getBigDecimal("yem_exwrmbprice");// 2023/12/21 zzs XQ-CLYX-20231011-0136_14
                            materialInfo.set("yem_newprice", price);
                            materialInfo.set("yem_newsalediffprice", saFobPrice.subtract(price));
                        }
                    }
                }
            }
            SaveServiceHelper.save(new DynamicObject[]{dataEntitie});
            view.updateView();
        }
    }

    /**
     * 1、外销合同、订舱通知单、出口报关单，增加字段：起运港英文名称、目的港英文名称，都是文本-200，放到运输信息-目的港的后面；
     * 2、目的港和起运港是多选基础资料，所以  起运港英文名称  由 起运港的英文名称拼接生成，目的港英文名称  由  目的港的英文名称拼接生成，如果单据上的港口信息修改，需要出发对应英文字段的更新；
     *
     * @param model
     * @param
     */
    public static void genShipPortEnName(IDataModel model) {
        DynamicObject dataEntity = model.getDataEntity();
        DynamicObjectCollection shipports = dataEntity.getDynamicObjectCollection("yem_shipports");
        if (shipports.isEmpty()) {
            model.setValue("yem_shipportsename", "");
        }

        StringBuilder shipportEnName = new StringBuilder();
        for (DynamicObject shipport : shipports) {
            DynamicObject port = shipport.getDynamicObject("fbasedataid");
            if (port == null) continue;
            port = BusinessDataServiceHelper.loadSingle(port.getPkValue(), port.getDataEntityType().getName(), "yem_namecn");
            shipportEnName.append(port.getString("yem_namecn")).append(";");
        }

        if (shipportEnName.length() > 0) {
            if (shipportEnName.length() > 200) {
                throw new KDBizException("起运港英文名称超过200个字符！");
            }
            shipportEnName = new StringBuilder(shipportEnName.substring(0, shipportEnName.length() - 1));
            model.setValue("yem_shipportsename", shipportEnName.length() > 0 ? shipportEnName.substring(0, shipportEnName.length()) : "");
        }

//        view.updateView();
    }

    public static void genDescPortEnName(IDataModel model) {
        DynamicObject dataEntity = model.getDataEntity();
        DynamicObjectCollection destports = dataEntity.getDynamicObjectCollection("yem_destports");
        if (destports.isEmpty()) {
            model.setValue("yem_destportsename", "");
        }
        StringBuilder destportEnName = new StringBuilder();
        for (DynamicObject destport : destports) {
            DynamicObject port = destport.getDynamicObject("fbasedataid");
            if (port == null) continue;
            port = BusinessDataServiceHelper.loadSingle(port.getPkValue(), port.getDataEntityType().getName(), "yem_namecn");
            destportEnName.append(port.getString("yem_namecn")).append(";");
        }
        if (destportEnName.length() > 0) {
            if (destportEnName.length() > 200) {
                throw new KDBizException("目的港英文名称超过200个字符！");
            }
            destportEnName = new StringBuilder(destportEnName.substring(0, destportEnName.length() - 1));
            model.setValue("yem_destportsename", destportEnName.length() > 0 ? destportEnName.substring(0, destportEnName.length()) : "");
        }
    }

    /**
     * 外销合同、发运明细  商品明细维护海关编码时
     * 根据报关分类+海关编码 更新实际申报要素 和  报关单位
     *
     * @param model
     * @param view
     * @param rowIndex
     * @param hscode
     */
    public static void carryDeclaration(IDataModel model, IFormView view, int rowIndex, DynamicObject declarationEle, DynamicObject hscode) {
        Date yemYear = declarationEle.getDate("yem_year");
        Calendar nowCalendar = Calendar.getInstance();
        nowCalendar.setTime(new Date());
        int nowYear = nowCalendar.get(Calendar.YEAR);
        Calendar tempCalendar = Calendar.getInstance();
        if (yemYear == null) {
            doCleanDeclaration(model, view, rowIndex);
            return;
        }
        tempCalendar.setTime(yemYear);
        int tempYear = tempCalendar.get(Calendar.YEAR);
        if (nowYear == tempYear) {
            model.setValue("yem_declarationele", declarationEle, rowIndex);
            model.setValue("yem_actualfilingele", declarationEle.getString("name"), rowIndex);
            if (hscode != null) {
                model.setValue("yem_declareunit", hscode.getDynamicObject("yem_legalfirst"), rowIndex);
            }
        } else {
            doCleanDeclaration(model, view, rowIndex);
        }
    }

    /**
     * 清空对应字段值
     *
     * @param model
     * @param view
     * @param rowIndex
     */
    private static void doCleanDeclaration(IDataModel model, IFormView view, int rowIndex) {
        // 申报要素
        model.setValue("yem_declarationele", null, rowIndex);
        // 实际申报要素
        model.setValue("yem_actualfilingele", null, rowIndex);
        // 报关单位
        model.setValue("yem_declareunit", null, rowIndex);
    }

    public static Integer getLastSerNumber(String input) {

        String[] parts = input.split("-");
        String serialNumber = parts[parts.length - 1];

        String regex2 = "(\\d+)$";
        Pattern pattern = Pattern.compile(regex2);
        Matcher matcher = pattern.matcher(serialNumber);
        if (matcher.find()) {
            String lastNumber = matcher.group(1);
            return Integer.parseInt(lastNumber);
        } else {
            throw new RuntimeException("未找到匹配的数字");
        }
    }

    public static void setCustomBillno(DynamicObject dataEntity, IFormView view) {
        String billno = dataEntity.getString("billno");
        if (billno.isEmpty()) return;

        // 以字母+数字结尾
        String isLetterAndNum = ".*-(?=[A-Z]\\d+$).*";
        // 以字母结尾
        String isLetterEnd = ".*[A-Za-z]$";
        ;
        // 框架合同
        DynamicObject agreementew = dataEntity.getDynamicObject("yem_agreementew");

        String customBillno = null;

        // 有框架合同 且 最后一位不是字母+数字 (需要重新生成继承框架合同的合同号)
        if (agreementew != null && !billno.matches(isLetterAndNum)) {
            agreementew = BusinessDataServiceHelper.loadSingle(agreementew.getLong("id"), "yem_es_salescontrac");
            String framework = agreementew.getString("billno");
            DynamicObjectCollection collection = agreementew.getDynamicObjectCollection("yem_entryentitys");
            LinkedHashSet<String> set = new LinkedHashSet<>();
            for (DynamicObject dynamicObject : collection) {
                DynamicObject salecontract = dynamicObject.getDynamicObject("yem_salecontract");
                if (salecontract != null) {
                    String salecontractbillno = salecontract.getString("billno");
                    set.add(salecontractbillno);
                }
            }

            // 首次关联，设置为1
            if (set.isEmpty()) {
                customBillno = String.format("%s%s", framework, 1);
                Integer afterCheck = parallelCheck(customBillno, "yem_es_salesorder", isLetterAndNum);

                if (afterCheck > 0) {
                    customBillno = String.format("%s%s", framework, afterCheck);
                }
            } else {

                LinkedList<String> linkedList = new LinkedList<>(set);
                String lastSaleOrderBillno = linkedList.pollLast();
                int intValue;
                try {
                    intValue = getLastSerNumber(lastSaleOrderBillno != null ? lastSaleOrderBillno : "");
                    customBillno = String.format("%s%s", framework, intValue + 1);
                    Integer afterCheck = parallelCheck(customBillno, "yem_es_salesorder", isLetterAndNum);

                    if (afterCheck > 0) {
                        customBillno = String.format("%s%s", framework, afterCheck);
                    }

                } catch (Exception e) {
                    if (view != null) {
                        view.showTipNotification(String.format("合同号生成失败：%s", e.getMessage()));
                    }
                }
            }
        }

        // 有框架合同 且 最后一位是字母+数字（不需要重新生成）
        if (agreementew != null && billno.matches(isLetterAndNum)) {
            return;
        }

        // 无框架合同 且 最后一位是字母+数字 || 无框架合同 且 最后一位不是字母 （需要生成默认无关联框架合同的合同号）
        if (agreementew == null && (billno.matches(isLetterAndNum) || !billno.matches(isLetterEnd))) {
            customBillno = SalesOrderUtils.replaceSerialNumberWithLetters(billno, dataEntity.getDataEntityType().getName());
        }

        if (customBillno != null) {
            dataEntity.set("billno", customBillno);
            dataEntity.set("yem_exportcontractnum", customBillno);
            SaveServiceHelper.save(new DynamicObject[]{dataEntity});
        }
    }

    /**
     * 重复检查
     *
     * @param billno
     * @return
     */
    private static Integer parallelCheck(String billno, String formId, String regex) {
        String noSerNo = getNoSerPart(billno);

        int intValue = 0;
        QFilter qFilter = new QFilter("billno", QCP.like, noSerNo + "%");
        DynamicObject[] load = BusinessDataServiceHelper.load(formId, "id, billno", qFilter.toArray());
        if (load.length > 0) {
            List<Integer> list = new ArrayList<>();
            for (DynamicObject dynamicObject : load) {
                String existBillno = dynamicObject.getString("billno");
                Pattern r = Pattern.compile(regex);
                Matcher matcher = r.matcher(existBillno);
                if (matcher.find()) {
                    list.add(getLastSerNumber(existBillno));
                }
            }
            Collections.sort(list);
            if (!list.isEmpty()) {
                intValue = list.get(list.size() - 1);
            }
            return intValue + 1;
        } else {
            return -1;
        }
    }

    private static String getNoSerPart(String input) {
        String regex = "(.*)-\\d+$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(input);

        if (matcher.matches()) {
            return matcher.group(1);
        } else {
            return input;
        }
    }

    public static String getCustomShipDetailsBillno(DynamicObject dataEntity) {
        String billno = dataEntity.getString("billno");
        String regex = "\\d+$";
        Integer parallelCheck = parallelCheck(billno, "yem_shippingdetails", regex);
        if (parallelCheck == -1) {
            return String.format("%s-%s", billno, 1);
        } else {
            return String.format("%s-%s", billno, parallelCheck);
        }
    }

    public static DynamicObject[] getDeclarationElementsUseF7Select(IDataModel model, int rowIndex, String currentFilterKey) {
        // 业务分类 Z | P
        String businesssort = (String) model.getValue("yem_businesssort", rowIndex);


        DynamicObjectCollection entryEntity = model.getEntryEntity("yem_es_materialinfo");
        if (entryEntity.isEmpty()) return new DynamicObject[]{};
        DynamicObject entry = entryEntity.get(rowIndex);

        // 基础机型
        DynamicObject productmodel = entry.getDynamicObject("yem_productmodel");
        // 物料
        DynamicObject material = entry.getDynamicObject("yem_materiel");
        // 报关分类
        DynamicObject customclass = entry.getDynamicObject("yem_customclass");
        // 海关编码
        DynamicObject hscode = entry.getDynamicObject("yem_hscode");

        String selectfields = DynamicObjectUtil.getSelectfields("yem_bd_declarationele");

        DynamicObject products = null;
        if ("yem_es_storagetrans".equals(model.getDataEntityType().getName())) {
            products = (DynamicObject) model.getValue("yem_products", rowIndex);
        } else {
            products = (DynamicObject) model.getValue("yem_bd_products");
        }

        long id = 0L;
        QFilter qFilter = new QFilter("enable", QCP.equals, "1");
        String number = products.getString("number");

        DynamicObject billtype = (DynamicObject) model.getValue("yem_billtype");
        String type = billtype.getString("number");
        if (StringUtils.containsIgnoreCase(type, "zj")) {
            if ("Z".equals(businesssort)) {
                if (YEM.isNotEmpty(productmodel)) {
                    id = productmodel.getLong("yem_products.id");
                    qFilter.and(new QFilter("yem_bd_declarationele.yem_productstree.id", QCP.equals, id));
                    qFilter.and(new QFilter("enable", QCP.equals, "1"));
                }
            }
            if ("P".equals(businesssort)) {
                if (YEM.isNotEmpty(material)) {
                    id = material.getLong("id");
                    qFilter.and(new QFilter("yem_bd_declarationele.yem_material.id", QCP.equals, id));
                }
                if (number.contains("ZZJ")) {
                    qFilter.and(new QFilter("yem_producttype.id", QCP.in, getCompAndPartProduct("ZZJ")));
                }
                if (number.contains("TLJ")) {
                    qFilter.and(new QFilter("yem_producttype.id", QCP.in, getCompAndPartProduct("TLJ")));
                }
                if (number.contains("CC")) {
                    qFilter.and(new QFilter("yem_producttype.id", QCP.in, getCompAndPartProduct("CC")));
                }
            }
        } else {
            if ("P".equals(businesssort)) {
                if (YEM.isNotEmpty(material)) {
                    id = material.getLong("id");
                    qFilter.and(new QFilter("yem_bd_declarationele.yem_material.id", QCP.equals, id));
                }
                qFilter.and(new QFilter("yem_producttype.id", QCP.equals, products.getLong("id")));
            }
        }



//        if (qFilter != null && YEM.isNotEmpty(products)) {
//            qFilter.and(new QFilter("yem_producttype.id", QCP.equals, products.getLong("id")));
//        }

//        if ("yem_customclass".equals(currentFilterKey)) {
//            if (qFilter != null) {
//                return BusinessDataServiceHelper.load("yem_bd_declarationele", selectfields, qFilter.toArray());
//            }
//        }

        if ("yem_hscode".equals(currentFilterKey) && customclass != null) {
            qFilter.and(new QFilter("yem_customclass.id", QCP.equals, customclass.getLong("id")));
        }

//        if (qFilter != null) {
//            if (customclass != null && !"yem_customclass".equals(currentFilterKey)) {
//                qFilter.and(new QFilter("yem_customclass.id", QCP.equals, customclass.getLong("id")));
//            }
//
//            if (hscode != null && !"yem_hscode".equals(currentFilterKey)) {
//                qFilter.and(new QFilter("yem_hscodebase.id", QCP.equals, hscode.getLong("id")));
//            }
//        }

        return BusinessDataServiceHelper.load("yem_bd_declarationele", selectfields, qFilter.toArray());
    }

    public static DynamicObject[] getDeclarationElementsUseCarry(IDataModel model, int rowIndex, String currentFilterKey) {
        // 业务分类 Z | P
        String businesssort = (String) model.getValue("yem_businesssort", rowIndex);


        DynamicObjectCollection entryEntity = model.getEntryEntity("yem_es_materialinfo");
        if (entryEntity.isEmpty()) return new DynamicObject[]{};
        DynamicObject entry = entryEntity.get(rowIndex);

        // 基础机型
        DynamicObject productmodel = entry.getDynamicObject("yem_productmodel");
        // 物料
        DynamicObject material = entry.getDynamicObject("yem_materiel");
        // 报关分类
        DynamicObject customclass = entry.getDynamicObject("yem_customclass");
        // 海关编码
        DynamicObject hscode = entry.getDynamicObject("yem_hscode");

        String selectfields = DynamicObjectUtil.getSelectfields("yem_bd_declarationele");
        // 产品分类
        DynamicObject products = null;

        if ("yem_es_storagetrans".equals(model.getDataEntityType().getName())) {
            products = (DynamicObject) model.getValue("yem_products", rowIndex);
        } else {
            products = (DynamicObject) model.getValue("yem_bd_products");
        }

        String number = products.getString("number");

        long id = 0L;
        QFilter qFilter = new QFilter("enable", QCP.equals, "1");

        DynamicObject billtype = (DynamicObject) model.getValue("yem_billtype");
        String type = billtype.getString("number");
        if (StringUtils.containsIgnoreCase(type, "zj")) {
            if ("Z".equals(businesssort)) {
                if (YEM.isNotEmpty(productmodel)) {
                    id = productmodel.getLong("yem_products.id");
                    qFilter.and(new QFilter("yem_bd_declarationele.yem_productstree.id", QCP.equals, id));
                    qFilter.and(new QFilter("enable", QCP.equals, "1"));
                }
            }
            if ("P".equals(businesssort)) {
                if (YEM.isNotEmpty(material)) {
                    id = material.getLong("id");
                    qFilter.and(new QFilter("yem_bd_declarationele.yem_material.id", QCP.equals, id));
                }
                if (number.contains("ZZJ")) {
                    qFilter.and(new QFilter("yem_producttype.id", QCP.in, getCompAndPartProduct("ZZJ")));
                }
                if (number.contains("TLJ")) {
                    qFilter.and(new QFilter("yem_producttype.id", QCP.in, getCompAndPartProduct("TLJ")));
                }
                if (number.contains("CC")) {
                    qFilter.and(new QFilter("yem_producttype.id", QCP.in, getCompAndPartProduct("CC")));
                }
            }
        } else {
            if ("P".equals(businesssort)) {
                if (YEM.isNotEmpty(material)) {
                    id = material.getLong("id");
                    qFilter.and(new QFilter("yem_bd_declarationele.yem_material.id", QCP.equals, id));
                }
                qFilter.and(new QFilter("yem_producttype.id", QCP.equals, products.getLong("id")));
            }
        }

        if (customclass != null) {
            qFilter.and(new QFilter("yem_customclass.id", QCP.equals, customclass.getLong("id")));
        }

        if (hscode != null) {
            qFilter.and(new QFilter("yem_hscodebase.id", QCP.equals, hscode.getLong("id")));
        }

        return BusinessDataServiceHelper.load("yem_bd_declarationele", selectfields, qFilter.toArray());
    }

    private static Set<Long> getCompAndPartProduct(String number) {
        String[] type = {number, number + "PJ"};
        DynamicObject[] load = BusinessDataServiceHelper.load("yem_bd_productsgroup", "billno, id", new QFilter[]{new QFilter("number", "in", type)});
        Set<Long> ids = new HashSet<>();
        for (DynamicObject dynamicObject : load) {
            ids.add(dynamicObject.getLong("id"));
        }
        return ids;
    }

    /**
     * 获取物料库存以及库存差
     *
     * @param materialNumid
     * @param materialNum
     * @param yem_bd_products
     * @return
     */
    public static Map getinventoryseva(Long materialNumid, String materialNum, DynamicObject yem_bd_products) {
        Map map = new HashMap<>();
        //库存
        //国贸配件库
        BigDecimal easyem_gmpjqty = getSumEASqty(materialNum, "D");
        BigDecimal cmmpyem_gmpjqty = getSumCMMPQty(materialNum, "D", yem_bd_products);
        BigDecimal yem_gmpjqty = easyem_gmpjqty.add(cmmpyem_gmpjqty);
        map.put("yem_gmpjqty", yem_gmpjqty);
        //处理库存差
        //已采购
        BigDecimal yem_buyfromcmmp = getbuyfromcmmp(materialNum, yem_bd_products);
        BigDecimal tolreqqty = gettolreqqty(yem_bd_products, materialNumid);
        BigDecimal yem_qtysub = easyem_gmpjqty.add(cmmpyem_gmpjqty).subtract(tolreqqty);
        map.put("yem_qtysub", yem_qtysub);
        map.put("tolreqqty", tolreqqty);
        return map;
    }

    /**
     * @param materialNum 物料编码
     * @param a           仓库分类
     * @return
     */
    private static BigDecimal getSumEASqty(String materialNum, String a) {
        //通过仓库分类查询所有EAS的仓库
        DynamicObjectCollection whs = QueryServiceHelper.query("yem_warehouse", "id,useorg.number,number",
                new QFilter[]{new QFilter("yem_belong", QCP.equals, "A"), new QFilter("yem_sort", QCP.equals, a),
                        new QFilter("enable", QCP.equals, "1")});
        JSONArray storageOrgs = new JSONArray();
        Set storageOrgs1 = new HashSet();
        Set warehouses1 = new HashSet();
        JSONArray warehouses = new JSONArray();
        for (DynamicObject wh : whs) {
            String useorgnum = wh.getString("useorg.number");
            storageOrgs1.add(useorgnum);
            String whnum = wh.getString("number");
            warehouses1.add(whnum);
        }
        for (Object o : storageOrgs1) {
            storageOrgs.add(o);
        }
        for (Object o : warehouses1) {
            warehouses.add(o);
        }
        if (whs.size() == 0) {
            return BigDecimal.ZERO;
        }
        JSONObject json = new JSONObject();
        json.put("start", 0);
        json.put("len", 1000);
        json.put("storageOrgs", storageOrgs);
        json.put("warehouses", warehouses);
        json.put("materialNumFrom", materialNum);//物料起--必填
        json.put("materialNumTo", materialNum);//物料止--必填
        String s = RequestEAS.InventoryListServiceFacadeGetData(json.toString());
        JSONObject result = JSONObject.parseObject(s);
        JSONArray list = result.getJSONArray("list");
        BigDecimal qty = BigDecimal.ZERO;
        if (list.size() == 1000) {
            json.put("start", (json.getIntValue("start") + 1) * json.getIntValue("len"));
            s = RequestEAS.InventoryListServiceFacadeGetData(json.toString());
            result = JSONObject.parseObject(s);
            list.addAll(result.getJSONArray("list"));
        }
        for (int i = 0; i < list.size(); i++) {
            JSONObject o = (JSONObject) list.get(i);
            BigDecimal fRealQty = o.getBigDecimal("FRealQty");
            if (fRealQty == null) {
                qty = qty.add(BigDecimal.ZERO);
            } else {
                qty = qty.add(fRealQty);
            }
        }
        return qty;
    }

    /**
     * @param materialNum     物料编码
     * @param a               仓库分类
     * @param yem_bd_products
     * @return
     */
    private static BigDecimal getSumCMMPQty(String materialNum, String a, DynamicObject yem_bd_products) {
        //产品类型ID获取CMMP链接
        yem_bd_products = BusinessDataServiceHelper.loadSingle(yem_bd_products.getLong("id"), yem_bd_products.getDynamicObjectType().getName());
        Long topCplxid = RequestCmmp.getTopCplx(yem_bd_products);
        DynamicObject cmmpConn = QueryServiceHelper.queryOne("yem_cmmpconfig", "id", new QFilter[]{new QFilter("yem_cmmpconfigentry.yem_bd_productsgroupn.id", QCP.equals, topCplxid)});
        //通过CMMP链接跟仓库分类获取仓库
        DynamicObjectCollection whs = QueryServiceHelper.query("yem_warehouse", "number",
                new QFilter[]{new QFilter("yem_cmmpconfig.id", QCP.equals, cmmpConn.getLong("id")),
                        new QFilter("yem_sort", QCP.equals, a),
                        new QFilter("enable", QCP.equals, "1")});
        StringBuilder whsb = new StringBuilder();
        for (DynamicObject wh : whs) {
            whsb.append("'" + wh.getString("number") + "',");
        }
        whsb.append("''");
        String sql = "SELECT sum(canuse_num) from VIEW_MATER_STOCK_WM where MATER_CODE='" + materialNum + "' " + "and wh_code in(" + whsb.toString() + ") GROUP BY MATER_CODE";
        List<Map> canuse_nums = RequestCmmp.getFromCmmp(null, sql, yem_bd_products.getLong("id"));
        BigDecimal canuse_num = BigDecimal.ZERO;
        for (Map canuseNum : canuse_nums) {
            BigDecimal b = (BigDecimal) canuseNum.get("sum(canuse_num)");
            if (b == null) {
                canuse_num = canuse_num.add(BigDecimal.ZERO);
            } else {
                canuse_num = canuse_num.add(b);
            }
        }
        return canuse_num;
    }

    /**
     * 查询已采购数量
     *
     * @param materialNum
     * @param yemBdProducts
     * @return
     */
    private static BigDecimal getbuyfromcmmp(String materialNum, DynamicObject yemBdProducts) {
        //产品类型ID获取CMMP链接
        yemBdProducts = BusinessDataServiceHelper.loadSingle(yemBdProducts.getLong("id"), yemBdProducts.getDynamicObjectType().getName());
        Long topCplxid = RequestCmmp.getTopCplx(yemBdProducts);
        DynamicObject cmmpConn = QueryServiceHelper.queryOne("yem_cmmpconfig", "id", new QFilter[]{new QFilter("yem_cmmpconfigentry.yem_bd_productsgroupn.id", QCP.equals, topCplxid)});
        String sql1 = "SELECT sum(order_this) a from VIEW_APPLY_ENROUTE_WM where mater_code='" + materialNum + "' GROUP BY mater_code";
        List<Map> need_numlist = RequestCmmp.getFromCmmpWithConnId(cmmpConn.getLong("id"), sql1);
        BigDecimal needNum = BigDecimal.ZERO;
        for (Map map : need_numlist) {
            if (map.get("a") != null) {
                needNum = (BigDecimal) map.get("a");
            }
        }
        String sql2 = "SELECT sum(instock_qty) b from VIEW_APPLY_ENROUTE_WM where mater_code='" + materialNum + "' GROUP BY mater_code";
        List<Map> instock_qtylist = RequestCmmp.getFromCmmpWithConnId(cmmpConn.getLong("id"), sql2);
        BigDecimal instock_qty = BigDecimal.ZERO;
        for (Map map : instock_qtylist) {
            if (map.get("b") != null) {
                instock_qty = (BigDecimal) map.get("b");
            }
        }
        String sql3 = "SELECT sum(close_qty) c from VIEW_APPLY_ENROUTE_WM where mater_code='" + materialNum + "' GROUP BY mater_code";
        List<Map> close_qtylist = RequestCmmp.getFromCmmpWithConnId(cmmpConn.getLong("id"), sql3);
        BigDecimal close_qty = BigDecimal.ZERO;
        for (Map map : close_qtylist) {
            if (map.get("c") != null) {
                close_qty = (BigDecimal) map.get("c");
            }
        }
        return needNum.subtract(instock_qty).add(close_qty);
    }

//    private static BigDecimal gettolreqqty(long materialNumid) {
//        //备料（生产、采购）信息中(除本订单之外的)汇总
//        DynamicObjectCollection yem_stockqtys = QueryServiceHelper.query("yem_tracktaskconsole",
//                "yem_es_materialinfo.yem_qty", new QFilter[]{
//                        new QFilter("yem_es_materialinfo.yem_materiel.id", QCP.equals, materialNumid)});
//        BigDecimal stockqty = BigDecimal.ZERO;
//        for (DynamicObject yemStockqty : yem_stockqtys) {
//            BigDecimal bigDecimal = yemStockqty.getBigDecimal("yem_es_materialinfo.yem_qty");
//            if (bigDecimal != null) {
//                stockqty = stockqty.add(bigDecimal);
//            }
//        }
//        //调拨订单中调出仓库的仓库分类为（国贸各事业部仓库）的yem_qty(yem_iseas=true)
//        //获取仓库分类为（国贸各事业部仓库）id集合
//        DynamicObjectCollection whColl = QueryServiceHelper.query("yem_warehouse", "id",
//                new QFilter[]{new QFilter("yem_sort", QCP.equals, "D"),
//                        new QFilter("enable", QCP.equals, "1")});
//        ArrayList<Long> whids = new ArrayList<>();
//        for (DynamicObject wh : whColl) {
//            whids.add(wh.getLong("id"));
//        }
//        DynamicObjectCollection transqtyColl = QueryServiceHelper.query("yem_transferorder", "yem_es_materialinfo.yem_qty", new QFilter[]{new QFilter("yem_entryoutwarehouse.id", QCP.in, whids),//调出仓库的仓库分类为（国贸各事业部仓库）
//                new QFilter("yem_materiel.id", QCP.equals, materialNumid),//物料
//                new QFilter("yem_iseas", QCP.equals, true)//已同步EAS
//        });
//        BigDecimal transQty = BigDecimal.ZERO;
//        for (DynamicObject transObj : transqtyColl) {
//            BigDecimal b = transObj.getBigDecimal("yem_es_materialinfo.yem_qty");
//            if (b != null) {
//                transQty = transQty.add(b);
//            }
//        }
//        return stockqty.subtract(transQty);
//    }

    /**
     * 客户需求单、外销合同的价格条款为FCA时，贸易术语=价格条款+目的港.工厂
     *
     * @param model
     * @param view
     */
    public static void genTradeTermsDestports(IDataModel model, IFormView view) {
        DynamicObject priceitem = (DynamicObject) model.getValue("yem_priceitem");
        String priceitemString = "";
        if (priceitem != null) {
            priceitemString = priceitem.getString("name");
        }
        if ("FCA".equals(priceitemString)) {
            StringBuilder sb = new StringBuilder();
            sb.append("FCA ");
            DynamicObjectCollection destports = (DynamicObjectCollection) model.getValue("yem_destports");
            for (DynamicObject destport : destports) {
                DynamicObject port = destport.getDynamicObject("fbasedataid");
                if (port == null) continue;
                port = BusinessDataServiceHelper.loadSingle(port.getPkValue(), port.getDataEntityType().getName(), "yem_factory");
                if (!port.getString("yem_factory").isEmpty()) {
                    sb.append(port.getString("yem_factory")).append(";");
                }
            }
            if (sb.lastIndexOf(";") == sb.length() - 1) {
                sb.deleteCharAt(sb.length() - 1);
            }
            model.setValue("yem_tradeterms", sb.toString());
        }
    }

    /**
     * 客户需求单、外销合同的价格条款为FCA时，贸易术语=价格条款+目的港.工厂
     *
     * @param model
     * @param view
     */
    public static void genTradeTermsShipports(IDataModel model, IFormView view) {
        DynamicObject priceitem = (DynamicObject) model.getValue("yem_priceitem");
        String priceitemString = "";
        if (priceitem != null) {
            priceitemString = priceitem.getString("name");
        }
        if ("EXW".equals(priceitemString)) {
            StringBuilder sb = new StringBuilder();
            sb.append("EXW ");
            DynamicObjectCollection shipports = (DynamicObjectCollection) model.getValue("yem_shipports");
            for (DynamicObject shipport : shipports) {
                DynamicObject port = shipport.getDynamicObject("fbasedataid");
                if (port == null) continue;
                port = BusinessDataServiceHelper.loadSingle(port.getPkValue(), port.getDataEntityType().getName(), "yem_factory");
                if (!port.getString("yem_factory").isEmpty()) {
                    sb.append(port.getString("yem_factory")).append(";");
                }
            }
            if (sb.lastIndexOf(";") == sb.length() - 1) {
                sb.deleteCharAt(sb.length() - 1);
            }
            model.setValue("yem_tradeterms", sb.toString());
        }
    }

    /**
     * 价格提调控为FOB 或CIF CFR时，拼接贸易术语
     * @param dataEntity
     */
    public static void genTradeTerms(DynamicObject dataEntity, IFormView view)
    {
        // 价格条款
        DynamicObject priceitem = dataEntity.getDynamicObject("yem_priceitem");
        if (priceitem == null) return;
        String priceitemString = priceitem.getString("name");
        if (YEM.isEmpty(priceitemString)) return;
        // 起运港
        String shipportsename = dataEntity.getString("yem_shipportsename");
        // 目的港
        String destportsename = dataEntity.getString("yem_destportsename");
        if ("FOB".equals(priceitemString)) {
            dataEntity.set("yem_tradeterms", String.format("%s %s", priceitemString, shipportsename));
        } else if ("CIF".equals(priceitemString) || "CFR".equals(priceitemString)) {
            dataEntity.set("yem_tradeterms", String.format("%s %s", priceitemString, destportsename));
        }
        view.updateView("yem_tradeterms");
    }

    /**
     * 选择海关编码，携带退税率
     * @param model
     * @param rowIdx
     */
    public static void carryTaxRefundRate(IDataModel model, int rowIdx) {
        DynamicObject hscode = (DynamicObject) model.getValue("yem_hscode", rowIdx);
        if (hscode == null) return;
        hscode = BusinessDataServiceHelper.loadSingle(hscode.getPkValue(), hscode.getDynamicObjectType().getName());
        BigDecimal rebaterate = hscode.getBigDecimal("yem_rebaterate");
        model.setValue("yem_degrate", rebaterate, rowIdx);
    }

    public static void generatePartGiftEntry(IDataModel model) {
        DynamicObject dataEntity = model.getDataEntity(true);
        String isgiftgiveparts = dataEntity.getString("yem_isgiftgiveparts");

        if (!"A".equals(isgiftgiveparts)) return;

        BigDecimal exrate = dataEntity.getBigDecimal("yem_exrate");
        DynamicObjectCollection collection = dataEntity.getDynamicObjectCollection("yem_es_materialinfo");
        DynamicObjectCollection giftEntry = dataEntity.getDynamicObjectCollection("yem_es_salesorder_zp");
        giftEntry.clear();
        Map<Long, List<DynamicObject>> merge = new HashMap<>();

        for (DynamicObject dynamicObject : collection) {
            String businesssort = dynamicObject.getString("yem_businesssort");
            if (!"Z".equals(businesssort)) continue;

            DynamicObject productmodel = dynamicObject.getDynamicObject("yem_productmodel");
            if (YEM.isEmpty(productmodel)) continue;

            long key = productmodel.getLong("id");

            if (merge.containsKey(key)) {
                List<DynamicObject> exist = merge.get(key);
                exist.add(dynamicObject);
                merge.put(key, exist);
            } else {
                List<DynamicObject> list = new ArrayList<>();
                list.add(dynamicObject);
                merge.put(key, list);
            }
        }

        for (Map.Entry<Long, List<DynamicObject>> entry : merge.entrySet()) {
            Long productmodelId = entry.getKey();
            List<DynamicObject> value = entry.getValue();

            DynamicObject addNew = giftEntry.addNew();
            DynamicObject basemodelib = BusinessDataServiceHelper.loadSingle(productmodelId, "yem_bd_basemodelib");
            long products = basemodelib.getLong("yem_products.id");
            addNew.set("yem_giveproactype", products); // 产品机型

            BigDecimal qty = BigDecimal.ZERO;
            for (DynamicObject dynamicObject : value) {
                qty = qty.add(dynamicObject.getBigDecimal("yem_qty"));
            }

            addNew.set("yem_qtyint", qty); // 台数
            DynamicObject object = value.get(0);
            BigDecimal singlepartgiftmat = object.getBigDecimal("yem_singlepartgiftmat"); // 单台配件金额
            addNew.set("yem_singleamt", singlepartgiftmat); // 单台配件金额
            addNew.set("yem_singleamtlocal", singlepartgiftmat.multiply(exrate)); // 单台配件金额（本位币）
            BigDecimal amount = qty.multiply(singlepartgiftmat);
            addNew.set("yem_giveamt", amount); // 配件金额
            addNew.set("yem_giveamtbase", amount.multiply(exrate)); // 配件金额本位币
        }
    }

    public static List<Long> filterColor(IDataModel model, String entryKey) {
        ArrayList<Long> list = Lists.newArrayList();
        int idx = model.getEntryCurrentRowIndex(entryKey);
        String businesssort = (String) model.getValue("yem_businesssort", idx);
        DynamicObject products = (DynamicObject) model.getValue("yem_bd_products");
        if (products == null) return list;
        String number = products.getString("number");
        String typeStr = null;
        if (StringUtils.containsIgnoreCase(number, "ZZJ")) {
            typeStr = "ZZJ";
        }
        if (StringUtils.containsIgnoreCase(number, "TLJ")) {
            typeStr = "TLJ";
        }
        if (StringUtils.containsIgnoreCase(number, "CC")) {
            typeStr = "CC";
        }
        String isComp = "0";
        if ("Z".equals(businesssort)) {
            isComp = "1";
        }
        if ("P".equals(businesssort)) {
            isComp = "0";
        }
        if (YEM.isNotEmpty(typeStr)) {
            DynamicObject[] load = BusinessDataServiceHelper.load("yem_em_color", "id, number, name", new QFilter[]{
                    new QFilter("yem_products.number", "=", typeStr),
                    new QFilter("yem_iscomp", "=", isComp),
            });
            for (DynamicObject dynamicObject : load) {
                list.add(dynamicObject.getLong("id"));
            }
        }
        return list;
    }

    public static void carryFinalDestination(IDataModel model, IFormView view) {
        DynamicObject dataEntity = model.getDataEntity();
        DynamicObjectCollection shipports = dataEntity.getDynamicObjectCollection("yem_destports");
        if (!shipports.isEmpty()) {
            DynamicObject dynamicObject = shipports.get(0).getDynamicObject("fbasedataid");
            DynamicObject country = dynamicObject.getDynamicObject("yem_country");
            model.setValue("yem_finalcountry", country);
        }
    }
}
