package com.yem.rf.salescommission;

import com.yem.tws.common1.BigDecimalUtils;
import com.yem.wm.utils.RptUtil;
import com.yem.wm.utils.YEM;
import com.yem.wm.utils.groupfunc.GroupConcatFunction;
import com.yem.wm.utils.groupfunc.GroupConcatFunctionByComma;
import com.yem.wm.utils.groupfunc.GroupTopOneFunction;
import kd.bos.algo.DataSet;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.report.AbstractReportListDataPlugin;
import kd.bos.entity.report.FilterInfo;
import kd.bos.entity.report.ReportQueryParam;
import kd.bos.orm.ORM;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import org.apache.commons.compress.utils.Lists;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

import static com.yem.rf.utils.RFUtils.formatDate;
import static com.yem.rf.utils.RFUtils.getBaseQFilter;

/**
 * @Description: 出口报关明细报表
 * @link: <a href="https://docs.qq.com/sheet/DTEd5V2hGZU1MWW13?tab=v0l9g4">https://docs.qq.com/sheet/DTEd5V2hGZU1MWW13?tab=v0l9g4</>
 * @Date: 2024/9/4 10:04
 * @Created: by ZZSLL
 */

public class ExportDeclarationDetailsReportPlugin extends AbstractReportListDataPlugin {

    private static final String algoKey = ExportDeclarationDetailsReportPlugin.class.getName();


    @Override
    public DataSet query(ReportQueryParam param, Object o) throws Throwable {

        FilterInfo filter = param.getFilter();

        DataSet declaredocx = queryDeclareDocx(param);

        DataSet declaredocx_relation = queryDeclareDocx_Relation(param);

        DataSet exportinvoice = queryExportInvoice(param);

        DataSet salesorder_info = querySalesOrder_Info(param);

        DataSet dataSet;

        dataSet = declaredocx.leftJoin(declaredocx_relation)
                .on("merged_seq", "rl_merged_seq")
                .on("declaredocx_id", "declare_id_gp_fk")
                .select(RptUtil.getDataSetFiledAlias(declaredocx), RptUtil.getDataSetFiledAlias(declaredocx_relation))
                .finish();

        dataSet = dataSet.leftJoin(exportinvoice)
                .on("merged_id", "ddd_id_ei_entry_fk")
                .select(RptUtil.getDataSetFiledAlias(dataSet), RptUtil.getDataSetFiledAlias(exportinvoice))
                .finish();

        dataSet = dataSet.leftJoin(salesorder_info)
                .on("main_id", "detail_id_info_fk")
                .select(RptUtil.getDataSetFiledAlias(dataSet), RptUtil.getDataSetFiledAlias(salesorder_info))
                .finish();

        dataSet = dataSet.select(String.join(",", RptUtil.getDataSetFiledAlias(dataSet)) + "," +
                //原币离岸价
                "yem_amount - tmp_reightamtend - tmp_premiumamtcy yem_basefobamt");
        dataSet = dataSet.select(String.join(",", RptUtil.getDataSetFiledAlias(dataSet)) + "," +
                //人民币离岸价
                "yem_basefobamt * yem_baserate yem_cnyfobamt");
        dataSet = dataSet.select(String.join(",", RptUtil.getDataSetFiledAlias(dataSet)) + "," +
                //人民币离岸价与开票额差额
                "ROUND(yem_cnyfobamt - yem_cnyinvoiced, 2) yem_fobsubinvoiced");
        dataSet = dataSet.select(String.join(",", RptUtil.getDataSetFiledAlias(dataSet)) + "," +
                //美元离岸价
                "CASE WHEN yem_usdrate > 0 THEN yem_cnyfobamt / yem_usdrate ELSE 0.0 END yem_usdfobamt");
        dataSet = dataSet.select(String.join(",", RptUtil.getDataSetFiledAlias(dataSet)) + "," +
                //出口创汇
                "yem_usdfobamt + usd_sea_amt + usd_pmamt_amt yem_earning");
        dataSet = dataSet.select(String.join(",", RptUtil.getDataSetFiledAlias(dataSet)) + "," +
                //应退税额
                "yem_cnyfobamt * yem_degrate / 100 yem_refundabletax");

        StringBuilder sb = new StringBuilder();

        Date fexportdate_start = filter.getDate("yem_fexportdate_start");//出口日期
        Date fexportdate_end = filter.getDate("yem_fexportdate_end");//出口日期

        String fcontactno = filter.getString("yem_fcontactno");//合同号

        Long fcustomer = filter.getLong("yem_fcustomer");//客户

        String fladingno = filter.getString("yem_fladingno");//提单号


        sb.append("1=1");
        if (YEM.isNotEmpty(fexportdate_start)) {
            sb.append(" AND TO_DATE(yem_exportdate, 'yyyy-MM-dd') >= ").append(String.format("TO_DATE('%s','yyyy-MM-dd')", formatDate(fexportdate_start)));
        }
        if (YEM.isNotEmpty(fexportdate_end)) {
            sb.append(" AND TO_DATE(yem_exportdate, 'yyyy-MM-dd') <= ").append(String.format("TO_DATE('%s','yyyy-MM-dd')", formatDate(fexportdate_end)));
        }
        if (YEM.isNotEmpty(fcontactno)) {
            sb.append(" AND yem_contactno LIKE '%").append(fcontactno.trim()).append("%'");
        }
        if (YEM.isNotEmpty(fcustomer)) {
            sb.append(" AND yem_customer = ").append(fcustomer);
        }
        if (YEM.isNotEmpty(fladingno)) {
            sb.append(" AND yem_ladingno LIKE '%").append(fladingno.trim()).append("%'");
        }

        return dataSet.where(sb.toString());
    }


    /**
     * 查询出口报关单
     * 查询出口报关单.报关商品
     * @param param
     * @return
     */
    private DataSet queryDeclareDocx(ReportQueryParam param) {

        QFilter qFilter = getCommonDeclareDocxFilter(param);

        ArrayList<String> selectfields = Lists.newArrayList();
        selectfields.add("id declaredocx_id");
        selectfields.add("billno yem_declaredocxno");//出口报关单号
        selectfields.add("yem_es_declare_ec.seq merged_seq");//报关商品分录序号
        selectfields.add("yem_es_declare_ec.id merged_id");//报关商品分录序号
        selectfields.add("yem_custombrokers yem_custombrokers");//报关行
        selectfields.add("yem_cfscompnaytxt yem_cfscompnaytxt");//货代公司（文本）
        selectfields.add("yem_customer.id yem_customer");//订单客户
        selectfields.add("TO_CHAR(yem_exportdate, 'yyyy-MM-dd') yem_exportdate");//出口日期
        selectfields.add("yem_customer.group.id yem_customer_group");//买方所在国
        selectfields.add("yem_commcountry yem_destinationcount");//贸易国别-目的国
        selectfields.add("yem_es_declare_ec.yem_cusqty yem_qty");//数量
        selectfields.add("yem_es_declare_ec.yem_cushscode yem_hscode");//海关商品编码-出口商品代码
        selectfields.add("yem_es_declare_ec.yem_decmatericalname yem_cncustomclass");//报关分类名称-商品名称中文
        selectfields.add("yem_settlement yem_settlementxt");//结算方式-付款方式
        selectfields.add("yem_currency yem_currency");//结算币别-币别
        selectfields.add("yem_priceitem yem_priceitem");//价格条款-贸易方式
        selectfields.add("yem_es_declare_ec.yem_cusconsalesprice yem_unitprice");//单价
        selectfields.add("yem_es_declare_ec.yem_cusamount yem_amount");//金额
        selectfields.add("yem_realbringbillno yem_ladingno");//提单号
        selectfields.add("yem_sctcompnayname.id yem_sctcompnayname");//船公司
        selectfields.add("yem_cyreightamt yem_cyreightamt");//海运费币别
        selectfields.add("yem_cypmamt yem_cypmamt");//保费币别
        selectfields.add("yem_reightamtend yem_seausdamtsum");//海运费（原币）-海运费USD总价 //2024-11-25改为取结算币别，注释未修改
        selectfields.add("yem_premiumamtcy yem_premiumamt");//保费（原币）-保险费 //2024-11-25改为取结算币别，注释未修改
        selectfields.add("yem_usbexrate yem_usdrate");//美元汇率
        selectfields.add("yem_es_declare_ec.yem_taxrefundrates yem_degrate");//退税率
        selectfields.add("yem_declarenumber yem_declarationno");//报关单号
        selectfields.add("yem_es_declare_ec.yem_declarationelee yem_declarationeletxt");//实际申报要素-规格型号

        selectfields.add("yem_reightamtbase yem_reightamtbase");//海运费（本位币）
        selectfields.add("yem_premiumamtbase yem_premiumamtbase");//保费（本位币）

        selectfields.add("yem_reightamtend yem_reightamtend");//海运费（结算币别）
        selectfields.add("yem_premiumamtcy yem_premiumamtcy");//保费（结算币别）


        DataSet dataSet = ORM.create().queryDataSet(algoKey, "yem_es_declaredocx", String.join(",", selectfields), qFilter.toArray());

        dataSet = dataSet.select(String.join(",", RptUtil.getDataSetFiledAlias(dataSet)) + "," +
                // 2、海运费（美元）=海运费（本位币）/美元汇率；
                "CASE WHEN yem_usdrate > 0 THEN yem_reightamtbase / yem_usdrate ELSE 0.0 END usd_sea_amt, " +
                // 3、运保费（美元）=运保费（本位币）/美元汇率；
                "CASE WHEN yem_usdrate > 0 THEN yem_premiumamtbase / yem_usdrate ELSE 0.0 END usd_pmamt_amt, " +
                // 美元汇率（百）
                "yem_usdrate * 100 yem_usdratehund");

        DataSet aggPort = aggBaseDataPort(qFilter);

        dataSet = dataSet.leftJoin(aggPort)
                .on("declaredocx_id", "declaredocx_id_agg_port_fk")
                .select(RptUtil.getDataSetFiledAlias(dataSet), RptUtil.getDataSetFiledAlias(aggPort))
                .finish();

        dataSet = doAmountApportionment(dataSet);

        return dataSet;
    }

    /**
     * 金额分摊处理
     * @param dataSet
     * @return
     */
    private DataSet doAmountApportionment(DataSet dataSet) {
        dataSet = dataSet.addField("0.0", "yem_baseseaamt");//原币海运费
        dataSet = dataSet.addField("0.0", "yem_usdseaamt");//美元海运费
        dataSet = dataSet.addField("0.0", "yem_basepremiumamt");//原币保险费
        dataSet = dataSet.addField("0.0", "yem_usdpremiumamt");//美元保险费
        dataSet = dataSet.addField("0.0", "tmp_reightamtend");//海运费（结算币别）
        dataSet = dataSet.addField("0.0", "tmp_premiumamtcy");//保费（结算币别）
        dataSet = dataSet.addField("0", "yem_cnycurrency");//人民币币别
        dataSet = dataSet.addField("0", "yem_usdcurrency");//美元币别
        DynamicObject cny = BusinessDataServiceHelper.loadSingle("bd_currency", "id", new QFilter[]{new QFilter("number", "=", "CNY")});
        long cnyId = 0L;
        if (YEM.isNotEmpty(cny)) {
            cnyId = cny.getLong("id");
        }

        DynamicObject usd = BusinessDataServiceHelper.loadSingle("bd_currency", "id", new QFilter[]{new QFilter("number", "=", "USD")});
        long usdId = 0L;
        if (YEM.isNotEmpty(usd)) {
            usdId = usd.getLong("id");
        }
        dataSet = RptUtil.zeroNullNums(dataSet);
        DynamicObjectCollection collection = ORM.create().toPlainDynamicObjectCollection(dataSet.copy());
        Map<String, List<DynamicObject>> map = new LinkedHashMap<>();
        for (DynamicObject d : collection) {
            String declaredocxno = d.getString("yem_declaredocxno");
            List<DynamicObject> list;
            if (map.containsKey(declaredocxno)) {
                list = map.get(declaredocxno);
            } else {
                list = new ArrayList<>();
            }
            list.add(d);
            map.put(declaredocxno, list);
        }

        DynamicObjectCollection dc = new DynamicObjectCollection();

        for (Map.Entry<String, List<DynamicObject>> entry : map.entrySet()) {
            List<DynamicObject> value = entry.getValue();

            BigDecimal sumAmt = BigDecimal.ZERO;

            for (DynamicObject d : value) {
                BigDecimal amount = d.getBigDecimal("yem_amount");
                sumAmt = sumAmt.add(amount);
            }

            BigDecimal share_baseseaamt = BigDecimal.ZERO;//原币海运费分摊
            BigDecimal share_usdseaamt = BigDecimal.ZERO;//美元海运费分摊
            BigDecimal share_basepremiumamt = BigDecimal.ZERO;//原币保险费分摊
            BigDecimal share_usdpremiumamt = BigDecimal.ZERO;//美元保险费分摊
            BigDecimal share_tmp_reightamtend = BigDecimal.ZERO;//海运费（结算币别）分摊
            BigDecimal share_tmp_premiumamtcy = BigDecimal.ZERO;//保费（结算币别）分摊
            for (DynamicObject d : value) {
                BigDecimal amount = d.getBigDecimal("yem_amount");//金额
                BigDecimal seausdamtsum = d.getBigDecimal("yem_seausdamtsum");//海运费USD总价
                BigDecimal usdSeaAmt = d.getBigDecimal("usd_sea_amt");//海运费（美元）
                BigDecimal premiumamt = d.getBigDecimal("yem_premiumamt");//原币保险费
                BigDecimal usdPmamtAmt = d.getBigDecimal("usd_pmamt_amt");//美元保险费
                BigDecimal reightamtend = d.getBigDecimal("yem_reightamtend");//海运费（结算币别）
                BigDecimal premiumamtcy = d.getBigDecimal("yem_premiumamtcy");//保费（结算币别）

                BigDecimal rate = BigDecimalUtils.div(amount, sumAmt, 10);

                //原币海运费 = 金额/金额汇总*海运费（原币）
                BigDecimal baseseaamt = rate.multiply(seausdamtsum);
                baseseaamt = baseseaamt.setScale(2, RoundingMode.HALF_UP);

                //美元海运费 = 金额/金额汇总*海运费（美元）
                BigDecimal usdseaamt = rate.multiply(usdSeaAmt);
                usdseaamt = usdseaamt.setScale(2, RoundingMode.HALF_UP);

                //原币保险费 = 金额/金额汇总*保险费（原币）
                BigDecimal basepremiumamt = rate.multiply(premiumamt);
                basepremiumamt = basepremiumamt.setScale(2, RoundingMode.HALF_UP);

                //美元保险费 = 金额/金额汇总*保险费（美元）
                BigDecimal usdpremiumamt = rate.multiply(usdPmamtAmt);
                usdpremiumamt = usdpremiumamt.setScale(2, RoundingMode.HALF_UP);

                //海运费（结算币别）
                BigDecimal tmp_reightamtend = rate.multiply(reightamtend);
                tmp_reightamtend = tmp_reightamtend.setScale(2, RoundingMode.HALF_UP);

                //保费（结算币别）
                BigDecimal tmp_premiumamtcy = rate.multiply(premiumamtcy);
                tmp_premiumamtcy = tmp_premiumamtcy.setScale(2, RoundingMode.HALF_UP);

                if (isLastRow(d, value)) {
                    d.set("yem_baseseaamt", seausdamtsum.subtract(share_baseseaamt));//原币海运费
                    d.set("yem_usdseaamt", usdSeaAmt.subtract(share_usdseaamt));//美元海运费
                    d.set("yem_basepremiumamt", premiumamt.subtract(share_basepremiumamt));//原币保险费
                    d.set("yem_usdpremiumamt", usdPmamtAmt.subtract(share_usdpremiumamt));//美元保险费
                    d.set("tmp_reightamtend", reightamtend.subtract(share_tmp_reightamtend));//海运费（结算币别）
                    d.set("tmp_premiumamtcy", premiumamtcy.subtract(share_tmp_premiumamtcy));//保费（结算币别）
                } else {
                    share_baseseaamt = share_baseseaamt.add(baseseaamt);
                    share_usdseaamt = share_usdseaamt.add(usdseaamt);
                    share_basepremiumamt = share_basepremiumamt.add(basepremiumamt);
                    share_usdpremiumamt = share_usdpremiumamt.add(usdpremiumamt);
                    share_tmp_reightamtend = share_tmp_reightamtend.add(tmp_reightamtend);
                    share_tmp_premiumamtcy = share_tmp_premiumamtcy.add(tmp_premiumamtcy);

                    d.set("yem_baseseaamt", baseseaamt);//原币海运费
                    d.set("yem_usdseaamt", usdseaamt);//美元海运费
                    d.set("yem_basepremiumamt", basepremiumamt);//原币保险费
                    d.set("yem_usdpremiumamt", usdpremiumamt);//美元保险费
                    d.set("tmp_reightamtend", tmp_reightamtend);//海运费（结算币别）
                    d.set("tmp_premiumamtcy", tmp_premiumamtcy);//保费（结算币别）
                }

                d.set("yem_cnycurrency", cnyId);
                d.set("yem_usdcurrency", usdId);
                dc.add(d);
            }
        }
        return RptUtil.plainDataSet(algoKey, dataSet, dc);
    }

    private boolean isLastRow(DynamicObject d, List<DynamicObject> value) {
        return value.indexOf(d) == value.size() - 1;
    }


    /**
     * 查询出口报关 报关商品对照表
     * 查询需要拼接的字段，完成拼接
     * @param param
     * @return
     */
    private DataSet queryDeclareDocx_Relation(ReportQueryParam param) {

        QFilter qFilter = getCommonDeclareDocxFilter(param);

        ArrayList<String> selectfields = Lists.newArrayList();

        selectfields.add("id declare_id_gp_fk");
        selectfields.add("yem_es_declare_ecd.yem_fgseq rl_detail_seq");//商品明细序号
        selectfields.add("yem_es_declare_ecd.yem_decsourceentryidtext rl_detail_id");//商品明细分录行id
        selectfields.add("yem_es_declare_ecd.yem_decgoodsseq rl_merged_seq");//报关商品序号
        DataSet dataSet = ORM.create().queryDataSet(algoKey, "yem_es_declaredocx", String.join(",", selectfields), qFilter.toArray());
        dataSet = dataSet.select("CAST(rl_detail_seq as Integer) rl_detail_seq, CAST(rl_detail_id as Long) rl_detail_id, CAST(rl_merged_seq as Integer) rl_merged_seq, declare_id_gp_fk");

        DataSet declaredocx_detail = queryDeclareDocx_Detail(param);

        DataSet delivernotice = queryDeliverNotice(param);

        DataSet salesorder = querySalesOrder(param);

        dataSet = dataSet.leftJoin(declaredocx_detail)
                .on("rl_detail_id","detail_id")
                .select(RptUtil.getDataSetFiledAlias(dataSet), RptUtil.getDataSetFiledAlias(declaredocx_detail))
                .finish();

        dataSet = dataSet.leftJoin(delivernotice)
                .on("main_order_id_ddd_fk", "dn_main_id_fk")
                .select(RptUtil.getDataSetFiledAlias(dataSet), RptUtil.getDataSetFiledAlias(delivernotice))
                .finish();

        dataSet = dataSet.leftJoin(salesorder)
                .on("main_order_id_ddd_fk", "main_id")
                .select(RptUtil.getDataSetFiledAlias(dataSet), RptUtil.getDataSetFiledAlias(salesorder))
                .finish();

        DataSet infoDataSet1 = dataSet.copy().groupBy(new String[]{"declare_id_gp_fk", "rl_merged_seq"})
                .agg(new GroupConcatFunctionByComma(), "yem_bizdate", "yem_shipdate")
                .agg(new GroupConcatFunctionByComma(), "yem_contactno", "yem_contactno")
                .finish()
                .select("declare_id_gp_fk declare_id_gp_fk_1, rl_merged_seq rl_merged_seq_1, yem_shipdate, yem_contactno");

        DataSet infoDataSet2 = dataSet.copy().groupBy(new String[]{"declare_id_gp_fk", "rl_merged_seq"})
                .agg(new GroupTopOneFunction(), "rl_detail_id", "rl_detail_id")
                .agg(new GroupTopOneFunction(), "main_id", "main_id")
                .agg(new GroupTopOneFunction(), "yem_orderno", "yem_orderno")
                .agg(new GroupTopOneFunction(), "rl_merged_seq", "rl_merged_seq")
                .finish()
                .select("declare_id_gp_fk declare_id_gp_fk_2, rl_merged_seq rl_merged_seq_2, rl_detail_id, main_id, yem_orderno, rl_merged_seq");

        dataSet = infoDataSet1.leftJoin(infoDataSet2)
                .on("declare_id_gp_fk_1", "declare_id_gp_fk_2")
                .on("rl_merged_seq_1", "rl_merged_seq_2")
                .select(RptUtil.getDataSetFiledAlias(infoDataSet1), RptUtil.getDataSetFiledAlias(infoDataSet2))
                .finish();

        dataSet = dataSet.select(String.join(",", RptUtil.getDataSetFiledAlias(dataSet)) + ", declare_id_gp_fk_1 declare_id_gp_fk");

        return dataSet;
    }

    /**
     * 查询出口报关 商品明细
     * @param param
     * @return
     */
    private DataSet queryDeclareDocx_Detail(ReportQueryParam param) {
        QFilter qFilter = getCommonDeclareDocxFilter(param);

        ArrayList<String> selectfields = Lists.newArrayList();

        selectfields.add("yem_es_materialinfo.id detail_id");
        selectfields.add("yem_es_materialinfo.yem_coreentryid main_order_id_ddd_fk");

        return ORM.create().queryDataSet(algoKey, "yem_es_declaredocx", String.join(",", selectfields), qFilter.toArray());
    }

    /**
     * 查询销售出库
     * @param param
     * @return
     */
    private DataSet queryDeliverNotice(ReportQueryParam param) {

        QFilter qFilter = getBaseQFilter();

        ArrayList<String> selectfields = Lists.newArrayList();

        selectfields.add("yem_es_materialinfo.yem_coreentryid dn_main_id_fk");//合同分录ID
        selectfields.add("yem_bizdate");//业务日期

        DataSet dataSet = ORM.create().queryDataSet(algoKey, "yem_es_delivernotice", String.join(",", selectfields), qFilter.toArray());
        dataSet = dataSet.select("dn_main_id_fk, TO_CHAR(yem_bizdate, 'yyyy-MM-dd') yem_bizdate");
        dataSet = dataSet.groupBy(new String[]{"dn_main_id_fk"})
                .agg(new GroupConcatFunctionByComma(), "yem_bizdate", "yem_bizdate")
                .finish();
        return dataSet;
    }


    /**
     * 查询外销合同
     * @param param
     * @return
     */
    private DataSet querySalesOrder(ReportQueryParam param) {

        QFilter qFilter = getBaseQFilter();

        ArrayList<String> selectfields = Lists.newArrayList();

        selectfields.add("yem_agreementew.billno framework_billno");//框架合同
        selectfields.add("yem_agreementew.billno framework_id");//框架合同
        selectfields.add("billno contact_billno");//外销合同号
        selectfields.add("yem_es_materialinfo.id main_id");//合同分录ID
        DataSet dataSet = ORM.create().queryDataSet(algoKey, "yem_es_salesorder", String.join(",", selectfields), qFilter.toArray());
        dataSet = dataSet.select("main_id, contact_billno, framework_id, framework_billno, " +
                // 有框架合同取框架合同号，否则取合同号
                "CASE WHEN framework_billno IS NOT NULL AND framework_billno != '' " +
                "THEN framework_billno " +
                "ELSE contact_billno " +
                "END yem_contactno, " +
                // 是否有框架合同，有1.0 没有0.0
                "CASE WHEN framework_billno IS NOT NULL AND framework_billno != '' " +
                "THEN 1.0 " +
                "ELSE 0.0 " +
                "END contains_framework_sign ");

        dataSet = dataSet.select(String.join(",", RptUtil.getDataSetFiledAlias(dataSet)) + "," +
                "CASE WHEN contains_framework_sign = 1 THEN contact_billno ELSE '' END yem_orderno");
//        DataSet framework = dataSet.copy().where("contains_framework_sign = 1.0");
//
//        framework = framework.groupBy(new String[]{"framework_billno"})
//                .agg(new GroupConcatFunctionByComma(), "contact_billno", "yem_orderno")
//                .finish();
//
//        framework = framework.select("framework_billno framework_billno_fk, yem_orderno");
//
//        dataSet = dataSet.leftJoin(framework)
//                .on("framework_billno", "framework_billno_fk")
//                .select(RptUtil.getDataSetFiledAlias(dataSet), RptUtil.getDataSetFiledAlias(framework))
//                .finish();

        return dataSet;
    }

    private DataSet querySalesOrder_Info(ReportQueryParam param) {
        QFilter qFilter = getBaseQFilter();

        ArrayList<String> selectfields = Lists.newArrayList();
        selectfields.add("yem_es_materialinfo.id detail_id_info_fk");
        selectfields.add("yem_operator yem_salesman");

        return ORM.create().queryDataSet(algoKey, "yem_es_salesorder", String.join(",", selectfields), qFilter.toArray());
    }

    public QFilter getCommonDeclareDocxFilter(ReportQueryParam param) {
        FilterInfo filter = param.getFilter();
        String fdeclaredocxno = filter.getString("yem_fdeclaredocxno");

        QFilter qFilter = getBaseQFilter();

        if (YEM.isNotEmpty(fdeclaredocxno)) {
            qFilter.and("billno", "=", fdeclaredocxno);
        }

        return qFilter;
    }

    /**
     * 查询多选基础资料、港口
     *
     * @param qFilter
     * @return
     */
    private DataSet aggBaseDataPort(QFilter qFilter) {

        ArrayList<String> selectfields = Lists.newArrayList();
        selectfields.add("id declaredocx_id_agg_port_fk");
        selectfields.add("yem_shipports.fbasedataid.name yem_departurport");//起运港
        selectfields.add("yem_destports.fbasedataid.name yem_destinationport");//目的港

        DataSet dataSet = ORM.create().queryDataSet(algoKey, "yem_es_declaredocx", String.join(",", selectfields), qFilter.toArray());

        dataSet = dataSet.groupBy(new String[]{"declaredocx_id_agg_port_fk"})
                .agg(new GroupConcatFunctionByComma(), "yem_departurport", "yem_departurport")
                .agg(new GroupConcatFunctionByComma(), "yem_destinationport", "yem_destinationport")
                .finish();
        return dataSet;
    }

    /**
     * 查询出口发票
     * @param param
     * @return
     */
    private DataSet queryExportInvoice(ReportQueryParam param) {

        QFilter qFilter = getBaseQFilter();

        ArrayList<String> selectfields = Lists.newArrayList();
        selectfields.add("billno exportinvoice_billno");
        selectfields.add("yem_exportinvoice_c.yem_customsdeclaration yem_unit");
        selectfields.add("yem_exportinvoice_c.yem_sourcebillentryid ddd_id_ei_entry_fk");
        selectfields.add("yem_exportinvoice_c.yem_localinvoicedamo yem_cnyinvoiced");//金额-人民币开票额
        selectfields.add("yem_exrate yem_baserate");//原币汇率
        selectfields.add("yem_invoicenumber yem_invoiceno");//发票号码
        DataSet dataSet = ORM.create().queryDataSet(algoKey, "yem_exportinvoice", String.join(",", selectfields), qFilter.toArray());
        dataSet = dataSet.select(String.join(",", RptUtil.getDataSetFiledAlias(dataSet)) + "," +
                //原币汇率（百）
                "yem_baserate * 100 yem_baserathund");
        return dataSet;
    }
}
