package com.yem.rf.salescommission;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.yem.ensign.common.DateUtils;
import com.yem.wm.utils.RequestCmmp;
import com.yem.wm.utils.RptUtil;
import com.yem.wm.utils.YEM;
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 kd.bos.servicehelper.QueryServiceHelper;
import org.apache.commons.compress.utils.Lists;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.*;

import static com.yem.rf.salescommission.CompleteShipDetailReportPlugin.*;
import static com.yem.rf.salescommission.SalesCommissionReportPlugin.queryGathering_ClaimedAmt_Total;
import static com.yem.rf.utils.RFUtils.getBaseQFilter;
import static com.yem.wm.utils.CalendarUtils.*;

/**
 * @Description: 发车日报
 * @Date: 2024/7/19 15:53
 * @Created: by ZZSLL
 */

public class DepartureDailyReportPlugin extends AbstractReportListDataPlugin {

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


    @Override
    public DataSet query(ReportQueryParam param, Object o) throws Throwable {
        FilterInfo filter = param.getFilter();
        Date fdate = filter.getDate("yem_fdate");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        DataSet dataSet;
        DataSet productype = queryProductType(param);//产品机型
        DataSet notreceivedqty = queryNotReceivedQty(param);//查询未收款数量
        DataSet receivedqty = queryReceivedRty(param);//查询已收定金数量
        DataSet contactbook_today = queryTodayContactBook(param);
        DataSet contactbook_mouth = queryMouthContactBook(param);
        DataSet contactbook_year = queryYearContactBook(param);
        DataSet yearlybudget_mouth = queryYearlyBudgetMouth(param);
        DataSet yearlybudget_year = queryYearlyBudgetYear(param);
        DataSet yearlybudget_year_total = queryYearlyBudgetYearTotal(param);


        dataSet = productype.addField("'" + sdf.format(fdate) + "'", "yem_date");

        dataSet = dataSet.leftJoin(notreceivedqty)
                .on("id", "order_product_id_main_fk")
                .select(RptUtil.getDataSetFiledAlias(dataSet), RptUtil.getDataSetFiledAlias(notreceivedqty))
                .finish();

        dataSet = dataSet.leftJoin(receivedqty)
                .on("id", "received_order_product_id_main_fk")
                .select(RptUtil.getDataSetFiledAlias(dataSet), RptUtil.getDataSetFiledAlias(receivedqty))
                .finish();

        dataSet = dataSet.leftJoin(contactbook_today)
                .on("id", "contactbook_product_id_main_fk_t")
                .select(RptUtil.getDataSetFiledAlias(dataSet), RptUtil.getDataSetFiledAlias(contactbook_today))
                .finish();

        dataSet = dataSet.leftJoin(contactbook_mouth)
                .on("id", "contactbook_product_id_main_fk_m")
                .select(RptUtil.getDataSetFiledAlias(dataSet), RptUtil.getDataSetFiledAlias(contactbook_mouth))
                .finish();

        dataSet = dataSet.leftJoin(contactbook_year)
                .on("id", "contactbook_product_id_main_fk_y")
                .select(RptUtil.getDataSetFiledAlias(dataSet), RptUtil.getDataSetFiledAlias(contactbook_year))
                .finish();

        dataSet = dataSet.leftJoin(yearlybudget_mouth)
                .on("id", "budget_product_id_main_fk")
                .select(RptUtil.getDataSetFiledAlias(dataSet), RptUtil.getDataSetFiledAlias(yearlybudget_mouth))
                .finish();

        dataSet = dataSet.leftJoin(yearlybudget_year)
                .on("id", "budget_product_id_main_fk_year")
                .select(RptUtil.getDataSetFiledAlias(dataSet), RptUtil.getDataSetFiledAlias(yearlybudget_year))
                .finish();

        dataSet = dataSet.leftJoin(yearlybudget_year_total)
                .on("id", "budget_product_id_main_fk_year_total")
                .select(RptUtil.getDataSetFiledAlias(dataSet), RptUtil.getDataSetFiledAlias(yearlybudget_year_total))
                .finish();

        dataSet = dataSet.addField("0.0", "yem_productid");
        dataSet = dataSet.addField("0.0", "yem_inventory");

        dataSet = dataSet.select(RptUtil.getDataSetFiledAlias(dataSet));

        StringBuilder sb = new StringBuilder();
        Set<String> set = Sets.newHashSet();
        String ftype = filter.getString("yem_ftype");
        String[] splits = ftype.split(",");
        for (String split : splits) {
            if (YEM.isNotEmpty(split)) set.add(split);
        }

        for (String item : set) {
            sb.append(" OR yem_proctype LIKE '%").append(item).append("%'");
        }

        if (set.contains("ZZJ")) {
            sb.append(" OR yem_proctype IN ('WJZZJ', 'WJJ') ");
        }

        final String prefix = " OR ";

        if (sb.length() >= prefix.length() && sb.substring(0, prefix.length()).equals(prefix)) {
            sb.delete(0, prefix.length());
            sb.insert(0, "(");
            sb.insert(sb.length(), ")");
        }

        DynamicObjectCollection fproctype = filter.getDynamicObjectCollection("yem_fproctype");

        if (YEM.isNotEmpty(fproctype) && !fproctype.isEmpty()) {
            sb.append(" AND yem_proctype IN (");
            for (DynamicObject dynamicObject : fproctype) {
                String number = dynamicObject.getString("number");
                sb.append("'").append(number).append("',");
            }
            sb.deleteCharAt(sb.length() - 1);
            sb.append(")");
        }

        dataSet = dataSet.where(sb.toString());

        dataSet = dataSet.select(RptUtil.getDataSetFiledAlias(dataSet));
        dataSet = dataSet.addField("0.0", "yem_budget_y_total");

        if (YEM.isEmpty(fproctype) || fproctype.isEmpty()) {
            dataSet = addSumLine(dataSet);
        }

        dataSet = fillWithCMMPQty(dataSet);

        dataSet = addTotalSumLine(dataSet);

        return dataSet;
    }

    /**
     * 业务分类为整机的产品类型2级分组，没有2级取1级
     *
     * @param param
     * @return
     */
    private DataSet queryProductType(ReportQueryParam param) {

        ArrayList<String> list = Lists.newArrayList();
        list.add("id");
        list.add("number");
        list.add("fullname");
        list.add("parent");
        list.add("enable");
        list.add("yem_businesssort");
        String selectfields = String.join(",", list);

        QFilter qFilter = new QFilter("enable", "=", "1");
        qFilter.and("yem_businesssort", "=", "Z");
        qFilter.and("parent.id", "=", 0);
        DataSet metaDataSet = ORM.create().queryDataSet(algoKey, "yem_bd_productsgroup", selectfields, qFilter.toArray());
        DynamicObjectCollection levelOneCollection = QueryServiceHelper.query("yem_bd_productsgroup", selectfields, qFilter.toArray());

        DynamicObjectCollection resCollection = new DynamicObjectCollection();

        for (DynamicObject dynamicObject : levelOneCollection) {
            long id = dynamicObject.getLong("id");
            QFilter twoQf = new QFilter("enable", "=", "1");
            twoQf.and("yem_businesssort", "=", "Z");
            twoQf.and("parent.id", "=", id);
            DynamicObjectCollection levelTwo = QueryServiceHelper.query("yem_bd_productsgroup", selectfields, twoQf.toArray());
            if (!levelTwo.isEmpty()) {
                resCollection.addAll(levelTwo);
            } else {
                resCollection.add(dynamicObject);
            }
        }

        //更新产品机型名称
        for (DynamicObject dynamicObject : resCollection) {
            String fullname = dynamicObject.getString("fullname");
            if (YEM.isNotEmpty(fullname)) {
                if (fullname.contains(".")) {
                    fullname = fullname.substring(0, fullname.indexOf("."));
                }
            }
            dynamicObject.set("fullname", fullname);
        }

        DataSet dataSet = RptUtil.plainDataSet(algoKey, metaDataSet, resCollection);
        dataSet = dataSet.select(String.join(",", RptUtil.getDataSetFiledAlias(dataSet)) + ",number yem_proctype, fullname yem_product").orderBy(new String[]{"yem_proctype DESC"});

        return dataSet;
    }

     /**
     * 查询已提交下单审批
     *
     * @param param
     * @return
     */
    private DataSet queryPlaceExamine(ReportQueryParam param) {
        QFilter qFilter = getBaseQFilter(new String[]{"B", "C"});

        List<String> selectfields = new ArrayList<>();
        selectfields.add("yem_sourcebillid source_order_id_placeexamine_fk");

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


    /**
     * 合同已下单（下单审批提交或者审核），但是合同款项未认领
     *
     * @param param
     * @return
     */
    private DataSet queryNotReceivedQty(ReportQueryParam param) {

        DataSet claimedAmt = queryGathering_ClaimedAmt_Total();

        DataSet dataSet;
        DataSet placeexamine = queryPlaceExamine(param);//BC下单审批
        DataSet salesorder = querySalesOrder(param);

        dataSet = placeexamine.leftJoin(salesorder)
                .on("source_order_id_placeexamine_fk", "order_id")
                .select(RptUtil.getDataSetFiledAlias(placeexamine), RptUtil.getDataSetFiledAlias(salesorder))
                .finish();
        dataSet = dataSet.leftJoin(claimedAmt)
                .on("order_id", "main_id_g_claimed_amt_fk")
                .select(RptUtil.getDataSetFiledAlias(dataSet), RptUtil.getDataSetFiledAlias(claimedAmt))
                .finish();
        dataSet = RptUtil.zeroNullNums(dataSet);

        dataSet = dataSet.where("yem_salcontractclaamt = NULL OR yem_salcontractclaamt = 0.0 ");

        dataSet = dataSet
                .groupBy(new String[]{"order_product_id_main_fk"})
                .sum("yem_qty")
                .finish();

        dataSet = dataSet.select("order_product_id_main_fk, yem_qty yem_nooay");

        return dataSet;
    }

    /**
     * 合同已下单（下单审批提交或者审核），且合同的预收款全部认领完成的数量
     *
     * @param param
     * @return
     */
    private DataSet queryReceivedRty(ReportQueryParam param) {

        DataSet dataSet;
        DataSet placeexamine = queryPlaceExamine(param);//BC下单审批
        DataSet salesorder = querySalesOrder(param);

        dataSet = placeexamine.leftJoin(salesorder)
                .on("source_order_id_placeexamine_fk", "order_id")
                .select(RptUtil.getDataSetFiledAlias(placeexamine), RptUtil.getDataSetFiledAlias(salesorder))
                .finish();
        dataSet = dataSet.select("order_id received_order_id, order_product_id_main_fk received_order_product_id_main_fk, yem_qty");

        ArrayList<Long> salesorderIds = new ArrayList<>();

        DynamicObjectCollection collection = ORM.create().toPlainDynamicObjectCollection(salesorder.copy());
        for (DynamicObject dynamicObject : collection) {
            salesorderIds.add(dynamicObject.getLong("order_id"));
        }

        DataSet payRate = querySalesOrder_PayRate(salesorderIds);

        DataSet claimDate = queryGathering_ClaimDate(salesorderIds, payRate);

        dataSet = dataSet.leftJoin(claimDate)
                .on("received_order_id", "main_id_gathering_fk")
                .select(RptUtil.getDataSetFiledAlias(dataSet), RptUtil.getDataSetFiledAlias(claimDate))
                .finish();

        dataSet = dataSet.where("yem_prodpaydate != NULL AND yem_prodpaydate != '' AND yem_shippaydate != NULL AND yem_shippaydate != ''");

        dataSet = dataSet
                .groupBy(new String[]{"received_order_product_id_main_fk"})
                .sum("yem_qty")
                .finish();
        dataSet = dataSet.select("received_order_product_id_main_fk, yem_qty yem_payed");

        return dataSet;
    }

    private DataSet querySalesOrder(ReportQueryParam param) {

        QFilter qFilter = getBaseQFilter();
        qFilter.and("yem_es_materialinfo.yem_businesssort", "=", "Z");
        List<String> selectfields = new ArrayList<>();

        selectfields.add("id order_id");
        selectfields.add("billno salesorder_no");
        selectfields.add("yem_es_materialinfo.yem_resourcenog.yem_products.group.id order_product_id_main_fk");
        selectfields.add("yem_es_materialinfo.yem_qty yem_qty");

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

    /**
     * 查询 本日发车量 发货联系书
     *
     * @param param
     * @return
     */
    private DataSet queryTodayContactBook(ReportQueryParam param) {
        FilterInfo filter = param.getFilter();
        Date fdate = filter.getDate("yem_fdate");

        QFilter qFilter = getBaseQFilter(new String[]{"B", "C"});
        qFilter.and("yem_es_materialinfo.yem_businesssort", "=", "Z");

        Date start = DateUtils.getBeginTime(fdate);

        Date end = DateUtils.getEndTime(fdate);

        qFilter.and("yem_vehicleeleatime", ">=", start);
        qFilter.and("yem_vehicleeleatime", "<=", end);

        List<String> selectfields = new ArrayList<>();

        selectfields.add("yem_es_materialinfo.yem_resourcenog.yem_products.group.id contactbook_product_id_main_fk_t");
        selectfields.add("yem_es_materialinfo.yem_qty yem_qty");

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

        dataSet = dataSet.select("contactbook_product_id_main_fk_t, yem_qty");

        dataSet = dataSet
                .groupBy(new String[]{"contactbook_product_id_main_fk_t"})
                .sum("yem_qty")
                .finish();

        dataSet = dataSet.select("contactbook_product_id_main_fk_t, yem_qty yem_today_ship");

        return dataSet;
    }

    /**
     * 查询 本月发车量 发货联系书
     *
     * @param param
     * @return
     */
    private DataSet queryMouthContactBook(ReportQueryParam param) {
        FilterInfo filter = param.getFilter();
        Date fdate = filter.getDate("yem_fdate");

        QFilter qFilter = getBaseQFilter(new String[]{"B", "C"});
        qFilter.and("yem_es_materialinfo.yem_businesssort", "=", "Z");

        Date firstDayOfMonth = getFirstDayOfMonth(fdate);

        Date lastDayOfMonth = getLastDayOfMonth(fdate);

        qFilter.and("yem_vehicleeleatime", ">=", firstDayOfMonth);

        qFilter.and("yem_vehicleeleatime", "<=", lastDayOfMonth);

        List<String> selectfields = new ArrayList<>();

        selectfields.add("yem_es_materialinfo.yem_resourcenog.yem_products.group.id contactbook_product_id_main_fk_m");
        selectfields.add("yem_es_materialinfo.yem_qty yem_qty");

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

        dataSet = dataSet.select("contactbook_product_id_main_fk_m, yem_qty");

        dataSet = dataSet
                .groupBy(new String[]{"contactbook_product_id_main_fk_m"})
                .sum("yem_qty")
                .finish();
        dataSet = dataSet.select("contactbook_product_id_main_fk_m, yem_qty yem_mouth_ship");
        return dataSet;
    }

    /**
     * 查询 本年发车量 发货联系书
     *
     * @param param
     * @return
     */
    private DataSet queryYearContactBook(ReportQueryParam param) {
        FilterInfo filter = param.getFilter();
        Date fdate = filter.getDate("yem_fdate");

        QFilter qFilter = getBaseQFilter(new String[]{"B", "C"});
        qFilter.and("yem_es_materialinfo.yem_businesssort", "=", "Z");

        Date firstDayOfYear = getFirstDayOfYear(fdate);

        Date lastDayOfYear = getLastDayOfYear(fdate);

        qFilter.and("yem_vehicleeleatime", ">=", firstDayOfYear);

        qFilter.and("yem_vehicleeleatime", "<=", lastDayOfYear);

        List<String> selectfields = new ArrayList<>();

        selectfields.add("yem_es_materialinfo.yem_resourcenog.yem_products.group.id contactbook_product_id_main_fk_y");
        selectfields.add("yem_es_materialinfo.yem_qty yem_qty");
        selectfields.add("billno");

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

        dataSet = dataSet.select("contactbook_product_id_main_fk_y, yem_qty");

        dataSet = dataSet
                .groupBy(new String[]{"contactbook_product_id_main_fk_y"})
                .sum("yem_qty")
                .finish();
        dataSet = dataSet.select("contactbook_product_id_main_fk_y, yem_qty yem_year_ship");
        return dataSet;
    }

    /**
     * 查询年度预算单（月份）
     *
     * @param param
     * @return
     */
    private DataSet queryYearlyBudgetMouth(ReportQueryParam param) {

        FilterInfo filter = param.getFilter();
        Date fdate = filter.getDate("yem_fdate");
        String monthName = getMonthName(fdate);

        QFilter qFilter = getBaseQFilter();

        List<String> selectfields = new ArrayList<>();
        selectfields.add("yem_im_detailedinfor.yem_productmodel.group.id budget_product_id_main_fk");//产品类型ID
        selectfields.add(String.format("yem_im_detailedinfor.yem_im_monthlyplan.yem_%s yem_qty", monthName.toLowerCase()));

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

        dataSet = dataSet
                .groupBy(new String[]{"budget_product_id_main_fk"})
                .sum("yem_qty")
                .finish();
        dataSet = dataSet.select("budget_product_id_main_fk, yem_qty yem_budget_mouth");
        return dataSet;
    }

    /**
     * 查询年度预算单
     *
     * @param param
     * @return
     */
    private DataSet queryYearlyBudgetYear(ReportQueryParam param) {

        FilterInfo filter = param.getFilter();
        Date fdate = filter.getDate("yem_fdate");
        Set<String> set = getMonthsFromStartOfYearToDate(fdate);
        QFilter qFilter = getBaseQFilter();

        List<String> selectfields = new ArrayList<>();
        Set<String> allMouth = Sets.newHashSet("yem_january", "yem_february", "yem_march", "yem_april", "yem_may", "yem_june", "yem_july", "yem_august", "yem_september", "yem_october", "yem_november", "yem_december");

        Set<String> subSet = new HashSet<>(allMouth);
        selectfields.add("yem_im_detailedinfor.yem_productmodel.group.id budget_product_id_main_fk_year");//产品类型ID
        for (String mouth : set) {
            selectfields.add(String.format("yem_im_detailedinfor.yem_im_monthlyplan.yem_%s yem_%s", mouth, mouth));
            subSet.remove("yem_" + mouth);
        }

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

        for (String mouth : subSet) {
            dataSet = dataSet.addField("0.0", mouth);
        }

        dataSet = dataSet.select("budget_product_id_main_fk_year, " + String.join(",", allMouth));
        dataSet = dataSet
                .groupBy(new String[]{"budget_product_id_main_fk_year"})
                .sum("yem_january")
                .sum("yem_february")
                .sum("yem_march")
                .sum("yem_april")
                .sum("yem_may")
                .sum("yem_june")
                .sum("yem_july")
                .sum("yem_august")
                .sum("yem_september")
                .sum("yem_october")
                .sum("yem_november")
                .sum("yem_december")
                .finish();
        dataSet = dataSet.select("budget_product_id_main_fk_year, " + String.join(",", allMouth));

        DynamicObjectCollection collection = ORM.create().toPlainDynamicObjectCollection(dataSet);
        for (DynamicObject obj : collection) {
            BigDecimal january = obj.getBigDecimal("yem_january");
            BigDecimal february = obj.getBigDecimal("yem_february");
            BigDecimal march = obj.getBigDecimal("yem_march");
            BigDecimal april = obj.getBigDecimal("yem_april");
            BigDecimal may = obj.getBigDecimal("yem_may");
            BigDecimal june = obj.getBigDecimal("yem_june");
            BigDecimal july = obj.getBigDecimal("yem_july");
            BigDecimal august = obj.getBigDecimal("yem_august");
            BigDecimal september = obj.getBigDecimal("yem_september");
            BigDecimal october = obj.getBigDecimal("yem_october");
            BigDecimal november = obj.getBigDecimal("yem_november");
            BigDecimal december = obj.getBigDecimal("yem_december");
            january = january.add(february).add(march).add(april).add(may).add(june).add(july).add(august).add(september).add(october).add(november).add(december);
            obj.set("yem_january", january);
        }

        return RptUtil.plainDataSet(algoKey, dataSet, collection).select("budget_product_id_main_fk_year, yem_january yem_budget_year");
    }


    private DataSet queryYearlyBudgetYearTotal(ReportQueryParam param) {
        FilterInfo filter = param.getFilter();
        Date fdate = filter.getDate("yem_fdate");
        Calendar calendar = Calendar.getInstance();

        calendar.setTime(fdate);

        calendar.set(Calendar.MONTH, Calendar.JANUARY);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Date startOfYear = calendar.getTime();

        calendar.add(Calendar.YEAR, 1);
        calendar.add(Calendar.SECOND, -1);
        Date endOfYear = calendar.getTime();

        QFilter qFilter = getBaseQFilter();
        qFilter.and("yem_bizdate", ">=", startOfYear);
        qFilter.and("yem_bizdate", "<=", endOfYear);

        Set<String> allMouth = Sets.newHashSet("yem_january", "yem_february", "yem_march", "yem_april", "yem_may", "yem_june", "yem_july", "yem_august", "yem_september", "yem_october", "yem_november", "yem_december");

        List<String> selectfields = new ArrayList<>();
        selectfields.add("yem_im_detailedinfor.yem_productmodel.group.id budget_product_id_main_fk_year_total");//产品类型ID
        for (String mouth : allMouth) {
            selectfields.add(String.format("yem_im_detailedinfor.yem_im_monthlyplan.%s %s", mouth, mouth));
        }

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

        dataSet = dataSet.select("budget_product_id_main_fk_year_total, " + String.join(",", allMouth));
        dataSet = dataSet
                .groupBy(new String[]{"budget_product_id_main_fk_year_total"})
                .sum("yem_january")
                .sum("yem_february")
                .sum("yem_march")
                .sum("yem_april")
                .sum("yem_may")
                .sum("yem_june")
                .sum("yem_july")
                .sum("yem_august")
                .sum("yem_september")
                .sum("yem_october")
                .sum("yem_november")
                .sum("yem_december")
                .finish();
        dataSet = dataSet.select("budget_product_id_main_fk_year_total, " + String.join(",", allMouth));

        DynamicObjectCollection collection = ORM.create().toPlainDynamicObjectCollection(dataSet);
        for (DynamicObject obj : collection) {
            BigDecimal january = obj.getBigDecimal("yem_january");
            BigDecimal february = obj.getBigDecimal("yem_february");
            BigDecimal march = obj.getBigDecimal("yem_march");
            BigDecimal april = obj.getBigDecimal("yem_april");
            BigDecimal may = obj.getBigDecimal("yem_may");
            BigDecimal june = obj.getBigDecimal("yem_june");
            BigDecimal july = obj.getBigDecimal("yem_july");
            BigDecimal august = obj.getBigDecimal("yem_august");
            BigDecimal september = obj.getBigDecimal("yem_september");
            BigDecimal october = obj.getBigDecimal("yem_october");
            BigDecimal november = obj.getBigDecimal("yem_november");
            BigDecimal december = obj.getBigDecimal("yem_december");
            january = january.add(february).add(march).add(april).add(may).add(june).add(july).add(august).add(september).add(october).add(november).add(december);
            obj.set("yem_january", january);
        }

        DataSet select = RptUtil.plainDataSet(algoKey, dataSet, collection).select("budget_product_id_main_fk_year_total, yem_january yem_budget_y_total_temp");
        return select;
    }

    /**
     * CMMP的可用库存，根据产品汇总
     * <br/>
     * <code>SELECT sum(canuse_num) FROM VIEW_MATER_STOCK_WM WHERE plan_pin IS NOT NULL<code/>
     *
     * @param dataSet
     * @return
     */
    private DataSet fillWithCMMPQty(DataSet dataSet) {

        DynamicObjectCollection originCollection = ORM.create().toPlainDynamicObjectCollection(dataSet);

        String sql = "SELECT sum(canuse_num) canuse_num FROM VIEW_MATER_STOCK_WM WHERE plan_pin IS NOT NULL";
        HashSet<Long> set = Sets.newHashSet();
        for (DynamicObject dynamicObject : originCollection) {
            long id = dynamicObject.getLong("yem_productid");
            if (id != 0) {
                set.add(id);
            }
        }

        for (Long productId : set) {
            List<Map> cmmp = RequestCmmp.getFromCmmp(0L, sql, productId);
            for (Map map : cmmp) {
                if (YEM.isEmpty(map)) continue;
                BigDecimal canuse_num = (BigDecimal) map.get("canuse_num");
                for (DynamicObject dataSetObj : originCollection) {
                    long id = dataSetObj.getLong("yem_productid");
                    if (id > 0) {

                        if (id == productId) {
                            dataSetObj.set("yem_inventory", canuse_num);
                        }
                    }
                }
            }
        }
        return RptUtil.plainDataSet(algoKey, dataSet, originCollection);
    }


    /**
     * 添加汇总行
     *
     * @param dataSet
     * @return
     */
    private DataSet addSumLine(DataSet dataSet) {
        DynamicObjectCollection originCollection = ORM.create().toPlainDynamicObjectCollection(dataSet);

        BigDecimal nppay = BigDecimal.ZERO;
        BigDecimal payed = BigDecimal.ZERO;
        BigDecimal day_ship = BigDecimal.ZERO;
        BigDecimal mouth_ship = BigDecimal.ZERO;
        BigDecimal year_ship = BigDecimal.ZERO;
        BigDecimal budget_mouth = BigDecimal.ZERO;
        BigDecimal budget_year = BigDecimal.ZERO;
        BigDecimal budget_year_total = BigDecimal.ZERO;

        HashMap<Integer, DynamicObject> map = Maps.newHashMap();

        for (DynamicObject currentObject : originCollection) {

            nppay = nppay.add(currentObject.getBigDecimal("yem_nooay"));
            payed = payed.add(currentObject.getBigDecimal("yem_payed"));
            day_ship = day_ship.add(currentObject.getBigDecimal("yem_today_ship"));
            mouth_ship = mouth_ship.add(currentObject.getBigDecimal("yem_mouth_ship"));
            year_ship = year_ship.add(currentObject.getBigDecimal("yem_year_ship"));
            budget_mouth = budget_mouth.add(currentObject.getBigDecimal("yem_budget_mouth"));
            budget_year = budget_year.add(currentObject.getBigDecimal("yem_budget_year"));
            budget_year_total = budget_year_total.add(currentObject.getBigDecimal("yem_budget_y_total_temp"));

            int index = originCollection.indexOf(currentObject);
            if (index <= 0) continue;
            DynamicObject preObject = originCollection.get(index - 1);
            String pre_proctype = preObject.getString("yem_proctype");
            String current_proctype = currentObject.getString("yem_proctype");
            boolean isLastRow = index == originCollection.size() - 1;
            if (current_proctype.contains("WJJ")) {//装载机汇总

                DynamicObject createObject = new DynamicObject(currentObject.getDynamicObjectType());

                createObject.set("yem_date", "");
                createObject.set("yem_product", "");
                createObject.set("yem_inventory", BigDecimal.ZERO);

                createObject.set("yem_proctype", "合计");
                createObject.set("yem_nooay", nppay);
                createObject.set("yem_payed", payed);
                createObject.set("yem_today_ship", day_ship);
                createObject.set("yem_mouth_ship", mouth_ship);
                createObject.set("yem_year_ship", year_ship);
                createObject.set("yem_budget_mouth", budget_mouth);
                createObject.set("yem_budget_year", budget_year);
                createObject.set("yem_budget_y_total", budget_year_total);

                DynamicObject zzj = BusinessDataServiceHelper.loadSingle("yem_bd_productsgroup", new QFilter[]{new QFilter("number", "=", "ZZJ")});
                createObject.set("yem_productid", zzj.getLong("id"));

                if (current_proctype.contains("WJJ")) {
                    map.put(index + 1, createObject);
                }

//                if ((pre_proctype.contains("ZZJ") || pre_proctype.contains("WJZZJ"))
//                        && !(current_proctype.contains("ZZJ") || current_proctype.contains("WJZZJ"))
//                ) {
//                    map.put(index, createObject);
//                }

                nppay = BigDecimal.ZERO;
                payed = BigDecimal.ZERO;
                day_ship = BigDecimal.ZERO;
                mouth_ship = BigDecimal.ZERO;
                year_ship = BigDecimal.ZERO;
                budget_mouth = BigDecimal.ZERO;
                budget_year = BigDecimal.ZERO;
                budget_year_total = BigDecimal.ZERO;

            } else if ((current_proctype.contains("CC") && !pre_proctype.contains("CC"))
                || (isLastRow && current_proctype.contains("TLJ"))
            ) {//拖拉机汇总

                DynamicObject createObject = new DynamicObject(currentObject.getDynamicObjectType());

                createObject.set("yem_date", "");
                createObject.set("yem_product", "");
                createObject.set("yem_inventory", BigDecimal.ZERO);

                createObject.set("yem_proctype", "合计");
                createObject.set("yem_nooay", nppay);
                createObject.set("yem_payed", payed);
                createObject.set("yem_today_ship", day_ship);
                createObject.set("yem_mouth_ship", mouth_ship);
                createObject.set("yem_year_ship", year_ship);
                createObject.set("yem_budget_mouth", budget_mouth);
                createObject.set("yem_budget_year", budget_year);
                createObject.set("yem_budget_y_total", budget_year_total);

                DynamicObject tlj = BusinessDataServiceHelper.loadSingle("yem_bd_productsgroup", new QFilter[]{new QFilter("number", "=", "TLJ")});
                createObject.set("yem_productid", tlj.getLong("id"));

                if (current_proctype.contains("CC") && !pre_proctype.contains("CC")) {
                    map.put(index, createObject);
                }
                if (isLastRow && current_proctype.contains("TLJ")) {
                    map.put(index + 1, createObject);
                }

                nppay = BigDecimal.ZERO;
                payed = BigDecimal.ZERO;
                day_ship = BigDecimal.ZERO;
                mouth_ship = BigDecimal.ZERO;
                year_ship = BigDecimal.ZERO;
                budget_mouth = BigDecimal.ZERO;
                budget_year = BigDecimal.ZERO;
                budget_year_total = BigDecimal.ZERO;

            } else if (current_proctype.contains("CC") && isLastRow) {//叉车汇总

                DynamicObject createObject = new DynamicObject(currentObject.getDynamicObjectType());

                createObject.set("yem_date", "");
                createObject.set("yem_product", "");
                createObject.set("yem_inventory", BigDecimal.ZERO);

                createObject.set("yem_proctype", "合计");
                createObject.set("yem_nooay", nppay);
                createObject.set("yem_payed", payed);
                createObject.set("yem_today_ship", day_ship);
                createObject.set("yem_mouth_ship", mouth_ship);
                createObject.set("yem_year_ship", year_ship);
                createObject.set("yem_budget_mouth", budget_mouth);
                createObject.set("yem_budget_year", budget_year);
                createObject.set("yem_budget_y_total", budget_year_total);

                DynamicObject cc = BusinessDataServiceHelper.loadSingle("yem_bd_productsgroup", new QFilter[]{new QFilter("number", "=", "CC")});
                createObject.set("yem_productid", cc.getLong("id"));

                map.put(-1, createObject);

                nppay = BigDecimal.ZERO;
                payed = BigDecimal.ZERO;
                day_ship = BigDecimal.ZERO;
                mouth_ship = BigDecimal.ZERO;
                year_ship = BigDecimal.ZERO;
                budget_mouth = BigDecimal.ZERO;
                budget_year = BigDecimal.ZERO;
                budget_year_total = BigDecimal.ZERO;
            }
        }

        for (Map.Entry<Integer, DynamicObject> mapEntry : map.entrySet()) {
            Integer idx = mapEntry.getKey();
            DynamicObject object = mapEntry.getValue();
            if (idx != -1) {
                originCollection.add(idx, object);
            } else {
                originCollection.add(originCollection.size(), object);
            }
        }

        return RptUtil.plainDataSet(algoKey, dataSet, originCollection);
    }

    /**
     * 添加总计行
     * @param dataSet
     * @return
     */
    private DataSet addTotalSumLine(DataSet dataSet) {
        DynamicObjectCollection originCollection = ORM.create().toPlainDynamicObjectCollection(dataSet);

        BigDecimal nppay = BigDecimal.ZERO;
        BigDecimal payed = BigDecimal.ZERO;
        BigDecimal day_ship = BigDecimal.ZERO;
        BigDecimal mouth_ship = BigDecimal.ZERO;
        BigDecimal year_ship = BigDecimal.ZERO;
        BigDecimal budget_mouth = BigDecimal.ZERO;
        BigDecimal budget_year = BigDecimal.ZERO;
        BigDecimal budget_year_total = BigDecimal.ZERO;
        BigDecimal inventory = BigDecimal.ZERO;

        for (DynamicObject currentObject : originCollection) {
            long id = currentObject.getLong("yem_productid");
            if (id == 0) {
                nppay = nppay.add(currentObject.getBigDecimal("yem_nooay"));
                payed = payed.add(currentObject.getBigDecimal("yem_payed"));
                day_ship = day_ship.add(currentObject.getBigDecimal("yem_today_ship"));
                mouth_ship = mouth_ship.add(currentObject.getBigDecimal("yem_mouth_ship"));
                year_ship = year_ship.add(currentObject.getBigDecimal("yem_year_ship"));
                budget_mouth = budget_mouth.add(currentObject.getBigDecimal("yem_budget_mouth"));
                budget_year = budget_year.add(currentObject.getBigDecimal("yem_budget_year"));
                inventory = inventory.add(currentObject.getBigDecimal("yem_inventory"));
            } else {
                budget_year_total = budget_year_total.add(currentObject.getBigDecimal("yem_budget_y_total"));
            }
        }

        DynamicObject createObject = new DynamicObject(originCollection.getDynamicObjectType());

        createObject.set("yem_date", "");
        createObject.set("yem_product", "");

        createObject.set("yem_proctype", "总计");
        createObject.set("yem_nooay", nppay);
        createObject.set("yem_payed", payed);
        createObject.set("yem_today_ship", day_ship);
        createObject.set("yem_mouth_ship", mouth_ship);
        createObject.set("yem_year_ship", year_ship);
        createObject.set("yem_budget_mouth", budget_mouth);
        createObject.set("yem_budget_year", budget_year);
        createObject.set("yem_budget_y_total", budget_year_total);

        createObject.set("yem_inventory", inventory);

        originCollection.add(originCollection.size(), createObject);
        return RptUtil.plainDataSet(algoKey, dataSet, originCollection);
    }
}