package nccloud.pubimpl.ic.inbound.generalin.operator;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.TimeZone;

import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.framework.common.NCLocator;
import nc.impl.pubapp.pattern.data.bill.BillQuery;
import nc.ui.pub.print.IDataSource;
import nc.ui.pub.print.IMetaDataDataSource;
import nc.vo.ic.general.define.ICBillBodyVO;
import nc.vo.ic.general.define.ICBillVO;
import nc.vo.ic.general.define.MetaNameConst;
import nc.vo.ic.m45.entity.PurchaseInVO;
import nc.vo.ic.m4d.entity.MaterialOutVO;
import nc.vo.ic.pub.define.ICPubMetaNameConst;
import nc.vo.pub.BusinessException;
import nc.vo.pub.CircularlyAccessibleValueObject;
import nc.vo.pub.SuperVO;
import nc.vo.pub.lang.UFDate;
import nc.vo.pub.lang.UFDateTime;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pub.lang.UFTime;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nc.vo.pubapp.pattern.model.entity.bill.AbstractBill;
import nc.vo.pubapp.pattern.model.entity.view.AbstractDataView;
import nc.vo.pubapp.scale.BillVOScaleProcessor;
import nc.vo.pubapp.scale.TotalValueVOScaleProcessor;
import nc.vo.pubapp.util.DefaultVOMerger;
import nc.vo.scmpub.res.billtype.ICBillType;
import nc.vo.scmpub.util.BillBodySortUtils;
import nc.vo.scmpub.util.ValueCheckUtil;
import nccloud.dto.ic.pub.entity.GeneralSumPrintInfo;
import nccloud.framework.core.json.IJson;
import nccloud.framework.web.json.JsonFactory;
import nccloud.pubitf.ic.pub.service.IICBillVOQueryService;
import nccloud.pubitf.platform.print.AbstractPrintService;
import nccloud.pubitf.platform.print.IPrintInfo;
import nccloud.pubitf.scmpub.pub.print.BaseMetaPrintTimesService;
import nccloud.pubitf.scmpub.pub.print.CombinePrintInfo;
import nccloud.pubitf.scmpub.pub.print.BaseMetaPrintTimesService.MetaDataSource;
import nccloud.pubitf.uap.print.vo.NoPreviewPrintInfo;
import nccloud.pubimpl.ic.inbound.purchasein.operator.PurchaseInVOPrecisionHandler;
import nccloud.pubimpl.ic.outbound.materialout.operator.MaterialOutVOPrecisionHandler;
import nccloud.pubimpl.ic.outbound.saleout.operator.SaleOutVOPrecisionHandler;
import nccloud.pubimpl.ic.pub.print.ICBasePrintVOPrecisionHandler;

/**
 * @author zhegnxinm
 * @version ncc1.0
 * @description 出入库汇总打印
 * @date 2018-12-16 上午10:48:39
 */

public class GeneralSumPrintOperator extends BaseMetaPrintTimesService {

    @Override
    public IDataSource[] getDataSources(IPrintInfo info) {
        GeneralSumPrintInfo printInfo = (GeneralSumPrintInfo) info;
        // 获取数据
        Object[] datas = this.getDatas(printInfo.getIds());
        if (ValueCheckUtil.isNullORZeroLength(datas)) {
            return null;
        }
        // 获取分组数据
        List<Boolean> alGroupBy = printInfo.getAlGroupBy();
        // 得到分组字段
        ICBillVO cvo = (ICBillVO) datas[0];
        String[] Fields = getGroupFields();
        String[] saGroupField = getSelGroupFields(alGroupBy, Fields);
        saGroupField = processSaGroupField(saGroupField);
        DefaultVOMerger dvomerger = new DefaultVOMerger();
        dvomerger.setGroupingAttr(saGroupField);
        // 得到Summing字段
        String[] saSummingField = null;
        if (cvo.getHead().getBillType().getCode().equals(ICBillType.MaterialOut.getCode())) {
            saSummingField = getSummingField((Boolean) alGroupBy.get(2));
        } else {
            saSummingField = getSummingField((Boolean) alGroupBy.get(2), printInfo.getInOutType());
        }
        dvomerger.setSummingAttr(saSummingField);
        //2025年6月27日11点22分 --扩展材料出库列表添加汇总合并
        if (cvo.getHead().getBillType().getCode().equals(ICBillType.MaterialOut.getCode())) {
            this.dealSumInfoDev(dvomerger, datas);
        } else {
            // 对表体分组
            try {
                ICBillBodyVO[] itemvosnew = (ICBillBodyVO[]) dvomerger.mergeByGroup(cvo
                        .getBodys());
                reSetPrice(itemvosnew, cvo.getHead().getBillType().getCode());
                cvo.setChildrenVO(itemvosnew);
            } catch (BusinessException e) {
                ExceptionUtils.wrappException(e);
            }
            //精度处理
            this.processData(cvo);
        }
        //是否敏感时区
        boolean isSensitive = InvocationInfoProxy.getInstance().getSensitiveTimeZone();
        if (isSensitive) {
            datas = this.processTimeZone(datas);
        }
        // 组装数据源
        IDataSource[] ds = this.getDataSource(datas);
        return ds;
    }

    private void dealSumInfoDev(DefaultVOMerger dvomerger, Object[] datas) {
        // 对表体分组
        try {
            for (Object data : datas) {
                ICBillVO cvo = (ICBillVO) data;

                ICBillBodyVO[] itemvosnew = (ICBillBodyVO[]) dvomerger.mergeByGroup(cvo
                        .getBodys());
                reSetPrice(itemvosnew, cvo.getHead().getBillType().getCode());
                cvo.setChildrenVO(itemvosnew);
                //精度处理
                this.processData(cvo);
            }
        } catch (BusinessException e) {
            ExceptionUtils.wrappException(e);
        }
    }

    @Override
    public Object[] getDatas(String[] ids) {
        BillQuery<PurchaseInVO> query45 = new BillQuery<PurchaseInVO>(PurchaseInVO.class);
        PurchaseInVO[] vos = query45.query(ids);
        if (vos.length != 0) {
            BillBodySortUtils.sort(vos);
            String pk_group = InvocationInfoProxy.getInstance().getGroupId();
            BillVOScaleProcessor scale = new BillVOScaleProcessor(pk_group, vos);
            TotalValueVOScaleProcessor totalScale = new TotalValueVOScaleProcessor(vos);

            PurchaseInVOPrecisionHandler handler = new PurchaseInVOPrecisionHandler(vos);
            handler.processVos(scale, totalScale);
            return vos;
        } else {
            BillQuery<MaterialOutVO> query4D = new BillQuery<MaterialOutVO>(MaterialOutVO.class);
            MaterialOutVO[] mvos = query4D.query(ids);
            BillBodySortUtils.sort(mvos);
            String pk_group = InvocationInfoProxy.getInstance().getGroupId();
            BillVOScaleProcessor scale = new BillVOScaleProcessor(pk_group, mvos);
            TotalValueVOScaleProcessor totalScale = new TotalValueVOScaleProcessor(mvos);

            PurchaseInVOPrecisionHandler handler = new PurchaseInVOPrecisionHandler(mvos);
            handler.processVos(scale, totalScale);
            return mvos;
        }
    }

    /**
     * 获取分组字段 方法功能描述：
     * <p>
     * <b>参数说明</b>
     *
     * @return <p>
     * @author zhangsui
     * @time 2011-7-19 上午08:37:31
     * @since 6.0
     */
    protected String[] getGroupFields() {
        return new String[]{ICPubMetaNameConst.CMATERIALVID,
                ICPubMetaNameConst.VBATCHCODE, ICPubMetaNameConst.CASTUNITID,
                "vfree0", ICPubMetaNameConst.CLOCATIONID,
                ICPubMetaNameConst.CVENDORID};
    }

    /**
     * 通过选择框最终确定的分组字段 方法功能描述：
     * <p>
     * <b>参数说明</b>
     *
     * @param alGroupBy
     * @param Fields
     * @return <p>
     * @author zhangsui
     * @time 2011-7-19 上午08:41:30
     * @since 6.0
     */
    @SuppressWarnings("unchecked")
    protected String[] getSelGroupFields(List alGroupBy, String[] Fields) {
        ArrayList alChooseGroup = new ArrayList();
        for (int i = 0; i < alGroupBy.size() - 1; i++) {
            if (((Boolean) alGroupBy.get(i)).booleanValue()) {
                alChooseGroup.add(Fields[i]);
            }
        }
        String[] saGroupField = null;
        if (alChooseGroup.size() > 0) {
            saGroupField = new String[alChooseGroup.size()];
            alChooseGroup.toArray(saGroupField);
        }
        return saGroupField;
    }

    /**
     * 对分组字段做特殊处理 方法功能描述：
     * <p>
     * <b>参数说明</b>
     *
     * @param saGroupField
     * @return <p>
     * @author zhangsui
     * @time 2011-7-19 下午03:13:03
     * @since 6.0
     */
    protected String[] processSaGroupField(String[] saGroupField) {
        List<String> fields = Arrays.asList(saGroupField);
        List<String> newfields = new ArrayList<String>();
        if (fields.contains("vfree0")) {
            for (int i = 0; i < saGroupField.length; i++) {
                if (!"vfree0".equals(saGroupField[i])) {
                    newfields.add(saGroupField[i]);
                }
            }
            for (int i = 1; i < 11; i++) {
                newfields.add("vfree" + i);
            }
            return newfields.toArray(new String[0]);
        }
        return saGroupField;
    }

    /**
     * 获取汇总字段 方法功能描述：
     * <p>
     * <b>参数说明</b>
     * 材料出库调用
     *
     * @param isselected
     * @return <p>
     * @author zhangsui
     * @time 2011-7-19 上午08:35:12
     * @since 6.0
     */

    protected String[] getSummingField(Boolean isselected) {
        String[] saSummingField = null;
        if ((isselected).booleanValue() == true) {
            saSummingField = new String[]{ICPubMetaNameConst.NSHOULDNUM,
                    ICPubMetaNameConst.NNUM, ICPubMetaNameConst.NASSISTNUM,
                    ICPubMetaNameConst.NSHOULDASSISTNUM, MetaNameConst.NCOSTMNY};
        } else {
            saSummingField = new String[]{ICPubMetaNameConst.NSHOULDNUM,
                    ICPubMetaNameConst.NNUM, MetaNameConst.NCOSTMNY};
        }
        return saSummingField;
    }

    /**
     * 获取汇总字段 方法功能描述：采购入库调用
     * <p>
     * <b>参数说明</b>
     *
     * @param isselected
     * @return <p>
     * @author zhangsui
     * @time 2011-7-19 上午08:35:12
     * @since 6.0
     */
    protected String[] getSummingField(Boolean isselected, String type) {
        String[] saSummingField = null;
        if ("in".equals(type)) {
            if ((isselected).booleanValue() == true) {
                saSummingField = new String[]{ICPubMetaNameConst.NSHOULDNUM,
                        ICPubMetaNameConst.NNUM, ICPubMetaNameConst.NASSISTNUM,
                        ICPubMetaNameConst.NSHOULDASSISTNUM,
                        MetaNameConst.NMNY,
                        /**
                         * 杭州锦江集团有限公司:采购入库汇总打印时部分字段没汇总
                        */
                        MetaNameConst.NORIGMNY, MetaNameConst.NCALCOSTMNY,
                        MetaNameConst.NTAXMNY, MetaNameConst.NORIGTAXMNY};
            } else {
                saSummingField = new String[]{ICPubMetaNameConst.NSHOULDNUM,
                        ICPubMetaNameConst.NNUM, MetaNameConst.NMNY};
            }
        } else if ("out".equals(type)) {
            if ((isselected).booleanValue() == true) {
                saSummingField = new String[]{ICPubMetaNameConst.NSHOULDNUM,
                        ICPubMetaNameConst.NNUM, ICPubMetaNameConst.NASSISTNUM,
                        ICPubMetaNameConst.NSHOULDASSISTNUM, MetaNameConst.NMNY};
            } else {
                saSummingField = new String[]{ICPubMetaNameConst.NSHOULDNUM,
                        ICPubMetaNameConst.NNUM, MetaNameConst.NMNY
                        /*
                         * 返回：打印模板中可合并计算的字段
                         * 现客户合并计算norigtaxmny(原币价税合计)的和，需要添加该字段的返回
                         */
                        , MetaNameConst.NORIGMNY, MetaNameConst.NTAXMNY,
                        MetaNameConst.NORIGTAXMNY};
            }
        }
        return saSummingField;
    }

    private void processData(ICBillVO cvo) {
        ICBillVO[] vos = new ICBillVO[]{cvo};
        //精度处理
        String pk_group = InvocationInfoProxy.getInstance().getGroupId();
        BillVOScaleProcessor scale = new BillVOScaleProcessor(pk_group, vos);
        TotalValueVOScaleProcessor totalScale = new TotalValueVOScaleProcessor(vos);
        ICBasePrintVOPrecisionHandler handler = null;
        if (vos[0].getHead().getBillType().getCode().equals(ICBillType.SaleOut.getCode())) {//销售出库
            ICBillVO[] aggvos = NCLocator.getInstance().lookup(IICBillVOQueryService.class).query(
                    ICBillType.SaleOut, new String[]{vos[0].getHead().getCgeneralhid()});
            if (aggvos == null || aggvos.length == 0) {
                ExceptionUtils.wrappBusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("4008027_0", "04008027-0180")/*@res "当前数据已被删除，请到列表页面刷新！"*/);
            }
            handler = new SaleOutVOPrecisionHandler(vos);
            handler.processVos(scale, totalScale);
        } else if (vos[0].getHead().getBillType().getCode().equals(ICBillType.MaterialOut.getCode())) {//材料出库
            ICBillVO[] aggvos = NCLocator.getInstance().lookup(IICBillVOQueryService.class).query(
                    ICBillType.MaterialOut, new String[]{vos[0].getHead().getCgeneralhid()});
            if (aggvos == null || aggvos.length == 0) {
                ExceptionUtils.wrappBusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("4008027_0", "04008027-0180")/*@res "当前数据已被删除，请到列表页面刷新！"*/);
            }
            handler = new MaterialOutVOPrecisionHandler(vos);
            handler.processVos(scale, totalScale);
        } else {//采购入库
            ICBillVO[] aggvos = NCLocator.getInstance().lookup(IICBillVOQueryService.class).query(
                    ICBillType.PurchaseIn, new String[]{vos[0].getHead().getCgeneralhid()});
            if (aggvos == null || aggvos.length == 0) {
                ExceptionUtils.wrappBusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("4008027_0", "04008027-0180")/*@res "当前数据已被删除，请到列表页面刷新！"*/);
            }
            handler = new PurchaseInVOPrecisionHandler(vos);
            handler.processVos(scale, totalScale);
        }
    }

    /**
     * 汇总以后重置价格 方法功能描述：
     * <p>
     * <b>参数说明</b>
     *
     * @param itemvosnew <p>
     * @author zhangsui
     * @time 2011-7-19 上午08:35:43
     * @since 6.0
     */
    protected void reSetPrice(ICBillBodyVO[] itemvosnew, String type) {
        if (itemvosnew != null) {
            UFDouble udNum = null;
            UFDouble udMny = null;
            for (int k = 0; k < itemvosnew.length; k++) {
                udNum = itemvosnew[k].getNnum();
                udMny = (UFDouble) itemvosnew[k]
                        .getAttributeValue(MetaNameConst.NMNY);
                if (type.equals(ICBillType.MaterialOut.getCode())) {
                    udMny = (UFDouble) itemvosnew[k]
                            .getAttributeValue(MetaNameConst.NCOSTMNY);

                } else {
                    udMny = (UFDouble) itemvosnew[k]
                            .getAttributeValue(MetaNameConst.NMNY);
                }
                if (udNum != null && udMny != null) {
                    itemvosnew[k].setAttributeValue(MetaNameConst.NPRICE,
                            (udMny.div(udNum)));
                }
            }
        }
    }

}
