package com.yem.rf.salescommission;


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 kd.bos.algo.DataSet;
import kd.bos.dataentity.entity.DynamicObject;
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.QCP;
import kd.bos.orm.query.QFilter;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

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

/**
 * @author ljw
 * @date 2024/7/22 11:48
 * @description ShipmentsChedulePlugin
 */
public class ShipmentsChedulePlugin extends AbstractReportListDataPlugin {
    private static final String algoKey = SalesCommissionReportPlugin.class.getName();

    @Override
    public DataSet query(ReportQueryParam reportQueryParam, Object o) throws Throwable {
        DataSet resDataSet;
        DataSet delivernotice = queryDeliverNotice(reportQueryParam);
        DataSet yemImTradeapp = yem_im_tradeapp(reportQueryParam);
        DataSet yemsDeclaredocx = yemsDeclaredocx(reportQueryParam);
        DataSet yemContainer = yemContainer();
        DataSet delivernotices = delivernotice(reportQueryParam);
        DataSet yem_es_delivernotice = yem_es_delivernotice(reportQueryParam);
        resDataSet = yemsDeclaredocx.leftJoin(yemContainer)
                .on("declaredocxyem_sourcebillid", "storagetransid")
                .select(RptUtil.getDataSetFiledAlias(yemsDeclaredocx), RptUtil.getDataSetFiledAlias(yemContainer))
                .finish();
        //发运明细
        resDataSet = resDataSet.leftJoin(delivernotice)
                .on("storagetransyemSourcebillid", "shippingdetailsid")//单据id  来源单据id
                .select(RptUtil.getDataSetFiledAlias(resDataSet), RptUtil.getDataSetFiledAlias(delivernotice))
                .finish();
        //销售出库
        resDataSet = resDataSet.leftJoin(yem_es_delivernotice)
                .on("shippingdetailsid", "delivernoticeyem_sourcebillid")//单据id  来源单据id
                .select(RptUtil.getDataSetFiledAlias(resDataSet), RptUtil.getDataSetFiledAlias(yem_es_delivernotice))
                .finish();
        resDataSet = resDataSet.leftJoin(delivernotices)
                .on("yem_es_materialinfoid", "declaredocxid")
                .select(RptUtil.getDataSetFiledAlias(resDataSet), RptUtil.getDataSetFiledAlias(delivernotices))
                .finish();
        //整机配件货款延付申请单
        resDataSet = resDataSet.leftJoin(yemImTradeapp)
                .on("shippingdetailsid", "tradeappyem_sourcebillid")//单据id  来源单据id
                .select(RptUtil.getDataSetFiledAlias(resDataSet), RptUtil.getDataSetFiledAlias(yemImTradeapp))
                .finish();
        DataSet selected = resDataSet.select(String.join(",", RptUtil.getDataSetFiledAlias(resDataSet)) +
                ",CASE WHEN DATEDIF(yem_lookoutdate,yem_datearrival,D) != -1  THEN DATEDIF(yem_lookoutdate,yem_datearrival,D) ELSE null END yem_flightnumberdays");
        FilterInfo filter = reportQueryParam.getFilter();
        String yemLading = filter.getString("yem_lading");
        String yemContract = filter.getString("yem_contract");
        DynamicObject yemClient = filter.getDynamicObject("yem_client");
        String yemShipping = filter.getString("yem_shipping");

        StringBuilder sb = new StringBuilder();
        sb.append("yem_customsdeclaration1 = 'B'");
        if (YEM.isNotEmpty(yemContract)) {
            sb.append("  AND  yem_contractnumber  like '").append("%").append(yemContract).append("%").append("'");
        }
        if (YEM.isNotEmpty(yemLading)) {
            sb.append("  AND  yem_ladingnumber  like '").append("%").append(yemLading).append("%").append("'");
        }
        if (YEM.isNotEmpty(yemClient)) {
            sb.append("  AND  yem_customername  = ").append("'" + yemClient.getString("name") + "'");
        }
        if (YEM.isNotEmpty(yemShipping)) {
            sb.append("  AND  yem_shipment  like  '").append("%").append(yemShipping).append("%").append("'");
        }
        DataSet where = selected.where(sb.toString());
        return where;
    }

    /**
     * 出口报关单
     */
    private DataSet yemsDeclaredocx(ReportQueryParam reportQueryParam) {


        //分票出提单（单证）    groupby
        FilterInfo filter = reportQueryParam.getFilter();
        QFilter qFilter = getBaseQFilter();
        Date start = filter.getDate("yem_Billofladingday");//提单日期-开始
        Date end = filter.getDate("yem_Lookoutdateawbday");//提单日期-结束
        qFilter.and("yem_sumopbill", QCP.equals, "B");
        if (YEM.isNotEmpty(start)) {
            qFilter.and("yem_tddate", ">=", start);
        }
        if (YEM.isNotEmpty(end)) {
            qFilter.and("yem_tddate", "<=", end);
        }
        qFilter.and("yem_customsdeclaration1", QCP.equals, "B");
        qFilter.and("yem_corebillid", QCP.not_equals, 0);
        List<String> selectfields = new ArrayList<>();
        selectfields.add("id yem_es_materialinfoid");
        selectfields.add("billno billno");
        selectfields.add("yem_es_declare_ec.yem_splitopbill yem_splitopbill");
        DataSet yemShippingdetails = ORM.create().queryDataSet(algoKey, "yem_es_declaredocx", String.join(",", selectfields), qFilter.toArray());
        yemShippingdetails = yemShippingdetails
                .groupBy(new String[]{"yem_splitopbill", "yem_es_materialinfoid"})
                .finish();
        DataSet rows = yemEsDeclaredocx(reportQueryParam);
        //获取值
        rows = rows.select(String.join(",", RptUtil.getDataSetFiledAlias(rows)) +
                ",case when  yem_bringbillno != '' THEN yem_bringbillno else yem_realbringbillno  end yem_ladingnumber");
        //出口报关
        yemShippingdetails = yemShippingdetails.leftJoin(rows)
                .on("yem_es_materialinfoid", "yem_es_declare_ecid")
                .select(RptUtil.getDataSetFiledAlias(yemShippingdetails), RptUtil.getDataSetFiledAlias(rows))
                .finish();
        return yemShippingdetails;
    }

    /**
     * 出口报关单
     */
    private DataSet yemEsDeclaredocx(ReportQueryParam reportQueryParam) {
        FilterInfo filter = reportQueryParam.getFilter();
        QFilter qFilter = getBaseQFilter();
        Date start = filter.getDate("yem_Billofladingday");//提单日期-开始
        Date end = filter.getDate("yem_Lookoutdateawbday");//提单日期-结束
        qFilter.and("yem_sumopbill", QCP.equals, "B");
        if (YEM.isNotEmpty(start)) {
            qFilter.and("yem_tddate", ">=", start);
        }
        if (YEM.isNotEmpty(end)) {
            qFilter.and("yem_tddate", "<=", end);
        }
        qFilter.and("yem_customsdeclaration1", QCP.equals, "B");
        List<String> selectfields = new ArrayList<>();
        selectfields.add("yem_customsdeclaration1");
        selectfields.add("id yem_es_declare_ecid");
        selectfields.add("yem_bizdate");
        selectfields.add("billno");
        selectfields.add("yem_bringbillno yem_bringbillno");//提单号
        selectfields.add("yem_realbringbillno yem_realbringbillno");//提单号
        selectfields.add("TO_CHAR(yem_ddpdate, 'yyyy-MM-dd') yem_customsclearance");//清关提货日
        selectfields.add("yem_sourcebillid declaredocxyem_sourcebillid");
        selectfields.add("yem_totalcontractno yem_contractnumber");
        DataSet yemShippingdetails = ORM.create().queryDataSet(algoKey, "yem_es_declaredocx", String.join(",", selectfields)
                , qFilter.toArray()).orderBy(new String[]{"yem_bizdate DESC"});

        return yemShippingdetails;
    }

    /**
     * 订舱通知单
     */
    private DataSet yemContainernumber() {
        QFilter qFilter = getBaseQFilter();
        List<String> selectfields = new ArrayList<>();

        //获取提单号，公司
        selectfields.add("id storagetransid");
        selectfields.add("yem_noticeno yem_noticeno");//提单号/运单号
//        selectfields.add("yem_es_materialinfo.yem_sourcebillno_d yem_sourcebillno_ds");//提单号/运单号
        selectfields.add("yem_housebillofladnum yem_housebillofladnum");//提单号/运单号
        selectfields.add("yem_docreview.fbasedataid.id yem_documenterss");//单证审核
        selectfields.add("yem_docreview.fbasedataid.name yem_documenter");//单证审核
        selectfields.add("yem_cfscompnay.name yem_forwardingcompanies");//货代公司
        selectfields.add("yem_sctcompnayname.name yem_shippingcompanies");//船公司
        selectfields.add("TO_CHAR(yem_tddate, 'yyyy-MM-dd') yem_lookoutdate");//提单日期
        selectfields.add("TO_CHAR(yem_arrivaldate, 'yyyy-MM-dd') yem_datearrival");//到港日
        selectfields.add("yem_sourcebillid storagetransyemSourcebillid");
        DataSet yemShippingdetails = ORM.create().queryDataSet(algoKey, "yem_es_storagetrans", String.join(",", selectfields), qFilter.toArray());
        yemShippingdetails = yemShippingdetails.distinct();
        //获取集装箱号
        List<String> selectfield = new ArrayList<>();
        selectfield.add("yem_mainladingno yem_mainladingno");//提单号/运单号
        selectfield.add("yem_im_encasement_ci.yem_encasenum yem_containernumbers");
        DataSet yemImEncasement = ORM.create().queryDataSet(algoKey, "yem_im_encasement", String.join(",", selectfield), qFilter.toArray());
        yemImEncasement = yemImEncasement.groupBy(new String[]{"yem_mainladingno"}).agg(new GroupConcatFunction(), "yem_containernumbers", "yem_containernumber").finish();
        //订舱通知单左连接装箱单
        yemShippingdetails = yemShippingdetails.leftJoin(yemImEncasement)
                .on("yem_noticeno", "yem_mainladingno")
                .select(RptUtil.getDataSetFiledAlias(yemShippingdetails), RptUtil.getDataSetFiledAlias(yemImEncasement))
                .finish();
        yemShippingdetails = yemShippingdetails.select(String.join(",", RptUtil.getDataSetFiledAlias(yemShippingdetails)) +
                ",case when  yem_noticeno != '' THEN yem_noticeno else yem_housebillofladnum  end yem_ladingnumbers");
        return yemShippingdetails;
    }

    /**
     * @return 订舱通知单
     */
    private DataSet yemContainer() {
        QFilter qFilter = getBaseQFilter();
        List<String> selectfields = new ArrayList<>();
        selectfields.add("id storagetransids");
        selectfields.add("yem_es_materialinfo.yem_sourcebillno_d yem_sourcebillno_d");//提单号/运单号
        DataSet yemShippingdetails = ORM.create().queryDataSet(algoKey, "yem_es_storagetrans", String.join(",", selectfields), qFilter.toArray());
        yemShippingdetails = yemShippingdetails
                .groupBy(new String[]{"storagetransids"}).agg(new GroupConcatFunctionByComma(), "yem_sourcebillno_d", "yem_shipment")
                .finish();
        DataSet yemContainernumber = yemContainernumber();
        yemShippingdetails = yemShippingdetails.leftJoin(yemContainernumber)
                .on("storagetransids", "storagetransid")//提单号
                .select(RptUtil.getDataSetFiledAlias(yemShippingdetails), RptUtil.getDataSetFiledAlias(yemContainernumber))
                .finish();
        return yemShippingdetails;
    }

    /**
     * 发运明细单
     *
     * @param reportQueryParam
     * @return
     */
    private DataSet queryDeliverNotice(ReportQueryParam reportQueryParam) {
        QFilter qFilter = getBaseQFilter();
        List<String> selectfields = new ArrayList<>();
        selectfields.add("id shippingdetailsid");
//        selectfields.add("yem_saleorderno yem_contractnumbers");//外销合同号
        selectfields.add("yem_issinosurecon yem_insurancecontract");//是否信保合同
        selectfields.add("yem_operator.name yem_salesman");//销售员
        selectfields.add("yem_customer.name yem_customername");//客户名称
        selectfields.add("yem_customer.group.name yem_customercountry");//客户所属国家
        selectfields.add("yem_clientcountry.name yem_tradingcountry");//贸易国别
        selectfields.add("yem_sourcebillid shippingdetailsyem_sourcebillid");
        return ORM.create().queryDataSet(algoKey, "yem_shippingdetails", String.join(",", selectfields), qFilter.toArray());
    }


    /**
     * 整机配件货款延付申请单
     *
     * @param reportQueryParam
     * @return
     */
    private DataSet yem_im_tradeapp(ReportQueryParam reportQueryParam) {
        QFilter qFilter = getBaseQFilter();
        List<String> selectfields = new ArrayList<>();
        selectfields.add("id tradeappid");
        selectfields.add("billno yem_money");//款项
        selectfields.add("yem_sourcebillid tradeappyem_sourcebillid");//来源单据ID
        DataSet yemShippingdetails = ORM.create().queryDataSet(algoKey, "yem_im_tradeapp", String.join(",", selectfields), qFilter.toArray());
        return yemShippingdetails;
    }

    /**
     * 销售出库
     */
    private DataSet yem_es_delivernotice(ReportQueryParam reportQueryParam) {
        QFilter qFilter = getBaseQFilter();
        List<String> selectfields = new ArrayList<>();
        selectfields.add("id delivernoticeid");
        selectfields.add("yem_bizdate yem_annual");//发货日期
        selectfields.add("yem_sourcebillid delivernoticeyem_sourcebillid");
        DataSet yemShippingdetails = ORM.create().queryDataSet(algoKey, "yem_es_delivernotice", String.join(",", selectfields), qFilter.toArray());
        return yemShippingdetails;
    }

    /**
     * 销售出库发货日期汇总
     */
    private DataSet delivernotice(ReportQueryParam reportQueryParam) {
        QFilter qFilter = getBaseQFilter();
        //销售出库
        List<String> selectfields = new ArrayList<>();
        selectfields.add("TO_CHAR(yem_bizdate, 'yyyy-MM-dd') yem_datebus");//发货日期
        selectfields.add("billno billnoaddes");
        selectfields.add("yem_sourcebillid delivernoticebillid");
        DataSet yem_es_delivernotice = ORM.create().queryDataSet(algoKey, "yem_es_delivernotice", String.join(",", selectfields), qFilter.toArray());
        yem_es_delivernotice = yem_es_delivernotice.groupBy(new String[]{"delivernoticebillid", "billnoaddes"}).agg(new GroupConcatFunction(), "yem_datebus", "yem_datebusin").finish();
        //出口报关
        FilterInfo filter = reportQueryParam.getFilter();
        QFilter qFilter1 = getBaseQFilter();
        Date start = filter.getDate("yem_Billofladingday");//提单日期-开始
        Date end = filter.getDate("yem_Lookoutdateawbday");//提单日期-结束
        qFilter1.and("yem_sumopbill", QCP.equals, "B");
        if (YEM.isNotEmpty(start)) {
            qFilter1.and("yem_tddate", ">=", start);
        }
        if (YEM.isNotEmpty(end)) {
            qFilter1.and("yem_tddate", "<=", end);
        }
        qFilter1.and("yem_customsdeclaration1", QCP.equals, "B");
        qFilter1.and("yem_corebillid", QCP.not_equals, 0);
        List<String> selectfield1 = new ArrayList<>();
        selectfield1.add("id declaredocxid");
        selectfield1.add("billno declaredocxbillno");
        selectfield1.add("yem_es_declare_ec.yem_splitopbill splitopbillyemid");
        selectfield1.add("yem_sourcebillid declaredocxyemid");
        DataSet yem_es_declaredocx = ORM.create().queryDataSet(algoKey, "yem_es_declaredocx", String.join(",", selectfield1), qFilter1.toArray());
        //订舱通知单
        List<String> selectfield2 = new ArrayList<>();
        selectfield2.add("id storagetranssid");
        selectfield2.add("yem_sourcebillid storagetransyemid");
        selectfield2.add("yem_es_materialinfo.yem_sgnenumber yem_sgnenumber");
        DataSet yem_es_storagetrans = ORM.create().queryDataSet(algoKey, "yem_es_storagetrans", String.join(",", selectfield2), qFilter.toArray());
        yem_es_storagetrans = yem_es_storagetrans.groupBy(new String[]{"storagetranssid", "yem_sgnenumber"}).finish();
        DataSet finish = yem_es_declaredocx.leftJoin(yem_es_storagetrans)
                .on("declaredocxyemid", "storagetranssid")
                .select(RptUtil.getDataSetFiledAlias(yem_es_declaredocx), RptUtil.getDataSetFiledAlias(yem_es_storagetrans))
                .finish();
        finish = finish.leftJoin(yem_es_delivernotice)
                .on("yem_sgnenumber", "billnoaddes")
                .select(RptUtil.getDataSetFiledAlias(finish), RptUtil.getDataSetFiledAlias(yem_es_delivernotice))
                .finish();
        finish = finish.groupBy(new String[]{"yem_datebusin", "declaredocxid", "splitopbillyemid"}).finish();
        finish = finish.groupBy(new String[]{"splitopbillyemid", "declaredocxid"})
                .agg(new GroupConcatFunction(), "yem_datebusin", "yem_datebusiness")
                .finish();
        return finish;
    }

}