package nccloud.api.impl.ic.m45;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import nc.impl.pubapp.pattern.data.vo.VOQuery;
import nc.vo.ic.org.OrgInfoQuery;
import nc.vo.pu.m23.entity.ArriveHeaderVO;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import nc.bs.scmpub.query.SCMBillQuery;
import nc.itf.scmpub.reference.uap.pf.PfServiceScmUtil;
import nc.pubimpl.ic.api.maintain.BillMaintainTool;
import nc.vo.ic.general.define.ICBillFlag;
import nc.vo.ic.general.define.ICBillHeadVO;
import nc.vo.ic.general.util.ICLocationUtil;
import nc.vo.ic.location.ICLocationVO;
import nc.vo.ic.m45.entity.PurchaseInBodyVO;
import nc.vo.ic.m45.entity.PurchaseInHeadVO;
import nc.vo.ic.m45.entity.PurchaseInVO;
import nc.vo.ic.pub.define.ICPubMetaNameConst;
import nc.vo.pub.BusinessException;
import nc.vo.pub.VOStatus;
import nc.vo.scmpub.check.billvalidate.BillVOsCheckRule;
import nc.vo.scmpub.res.billtype.ICBillType;
import nccloud.api.ic.m45.IAPIPurchaseInMaitain;
import nccloud.api.impl.ic.m45.check.CheckPurchaseInSaveValidator;
import nccloud.api.impl.ic.m45.fill.PurchaseInSaveFillValue;
import nccloud.api.impl.ic.m45.fill.PurchaseInUpdateFillValue;
import nccloud.api.impl.ic.pub.check.CheckProhibitUpdateFields;
import nccloud.openapi.ic.util.ICAPILocationVOUtils;
import nccloud.openapi.scmpub.pub.TransferCodeToPKTool;
import nccloud.openapi.scmpub.pub.TransferMapToVOTool;

/**
 * @version NCC1909
 * @Description: 库存采购入库单维护接口实现类
 * @author: 刘伟
 * @date: 2019-5-7 下午3:22:00
 */
public class APIPurchaseInMaitainImpl implements IAPIPurchaseInMaitain {

    @Override
    public PurchaseInVO[] save(List<Map<String, Object>> paramList)
            throws BusinessException {
        // MapList转聚合VOList
        List<PurchaseInVO> aggVOList =
                TransferMapToVOTool.transferMapToAggVO(paramList, PurchaseInVO.class);
        PurchaseInVO[] vos = aggVOList.toArray(new PurchaseInVO[aggVOList.size()]);
        // 设置货位序列号VO
        ICAPILocationVOUtils.setLocationVO(ICBillType.PurchaseIn.getCode(), vos);
        // 1、传入数据基本非空校验
        BillVOsCheckRule checker =
                new BillVOsCheckRule(new CheckPurchaseInSaveValidator());
        //2025年4月23日15点10分 采购入库单接口项目字段为波浪则清空 sdlizheng --start
        for (PurchaseInVO vo : vos) {
            PurchaseInBodyVO[] bodys = vo.getBodys();
            if (bodys != null && bodys.length > 0) {
                String[] attributeNames = bodys[0].getAttributeNames();
                for (PurchaseInBodyVO body : bodys) {
                    for (String fildName : attributeNames) {
                        if (body.getAttributeValue(fildName) != null && "~".equals(body.getAttributeValue(fildName))) {
                            body.setAttributeValue(fildName, null);
                        }
                    }
                }
            }

        }
        //2025年4月23日15点10分 采购入库单接口项目字段为波浪则清空 sdlizheng --end
        //添加供应商和交易类型为空赋值
        fillHeadDataBeforeCheck(vos);
        checker.check(vos);
        // 2、编码翻译成pk
        aggVOList = TransferCodeToPKTool.transferAggVO(aggVOList);
        // 翻译货位
        ICAPILocationVOUtils.translate(vos);

        //begin没取到财务组织导致的报错，在这里给财务组织赋值为库存组织
        for (PurchaseInVO vo : vos) {
            if (vo.getHead().getCfanaceorgoid() != null) {
                continue;
            }
            String cfinanceoid = (new OrgInfoQuery()).getFinanceOrgIDByCalBodyID(vo.getHead().getPk_org());
            String cfinancevid = (new OrgInfoQuery()).getFinanceOrgVIDByCalBodyID(vo.getHead().getPk_org());
            vo.getHead().setCfanaceorgoid(cfinanceoid);
            vo.getHead().setCfanaceorgvid(cfinancevid);
        }
        //end

        // 3、其他数据填充
        new PurchaseInSaveFillValue().setDefaultValue(vos);

        BillMaintainTool<PurchaseInVO> tool = new BillMaintainTool<PurchaseInVO>(
                PurchaseInVO.class, ICBillType.PurchaseIn.getCode());
        return tool.insert(vos);
    }

    private void fillHeadDataBeforeCheck(PurchaseInVO[] vos) {
        for (PurchaseInVO vo : vos) {
            if (StringUtils.isEmpty(vo.getHead().getVtrantypecode())) {
                //设置默认交易类型
                vo.getHead().setVtrantypecode("45-01");
            }
            if (StringUtils.isEmpty(vo.getHead().getCvendorid())) {
                //根据上游获取数据
                PurchaseInBodyVO[] bodys = vo.getBodys();
                String csourcetype = bodys[0].getCsourcetype();
                String csourcebillhid = bodys[0].getCsourcebillhid();
                if ("23".equals(csourcetype) && StringUtils.isNotEmpty(csourcebillhid)) {
                    //上游到货单
                    ArriveHeaderVO[] srcHVOs = new VOQuery<>(ArriveHeaderVO.class).query(new String[]{csourcebillhid});
                    if (ArrayUtils.isNotEmpty(srcHVOs)) {
                        vo.getHead().setCvendorid(srcHVOs[0].getPk_supplier());
                    }
                }
            }
        }
    }

    @Override
    public PurchaseInVO[] update(List<Map<String, Object>> paramList)
            throws BusinessException {
        // MapList转聚合VOList
        List<PurchaseInVO> aggVOList =
                TransferMapToVOTool.transferMapToAggVO(paramList, PurchaseInVO.class);
        PurchaseInVO[] vos = aggVOList.toArray(new PurchaseInVO[aggVOList.size()]);
        // 2、编码翻译成pk
        aggVOList = TransferCodeToPKTool.transferAggVO(aggVOList);
        Set<String> bfields = new HashSet<String>();
        PurchaseInHeadVO newVO = vos[0].getHead();
        String cgeneralhid = newVO.getCgeneralhid();
        if (StringUtils.isEmpty(cgeneralhid)) {
            throw new BusinessException(
                    nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("4008027_0",
                            "04008027-0380")/* @res "修改采购入库单请指定表头主键cgeneralhid值。" */);
        }
        SCMBillQuery<PurchaseInVO> queryTool =
                new SCMBillQuery<PurchaseInVO>(PurchaseInVO.class);
        PurchaseInVO[] purInVOs = queryTool.queryVOByIDs(new String[]{
                cgeneralhid
        });
        Map<String, ICLocationVO[]> deleteLoc =
                new HashMap<String, ICLocationVO[]>();
        // 加载原始单据和货位信息
        PurchaseInVO[] originBills = queryTool.queryVOByIDs(new String[]{
                cgeneralhid
        });
        ICLocationUtil.loadLocationVOs(originBills);
        if (ArrayUtils.isEmpty(purInVOs)) {
            throw new BusinessException(
                    nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("4008027_0",
                            "04008027-0381")/* @res "没找到要修改的入库单信息，请检查数据的表头主键cgeneralhid。" */);
        } else {
            List<String> headProFields =
                    CheckProhibitUpdateFields.getHeadProhibitFields("45");
            List<String> bodyProFields =
                    CheckProhibitUpdateFields.getBodyProhibitFields("45");
            PurchaseInHeadVO origVO = purInVOs[0].getHead();
            if (origVO.getFbillflag() == null
                    || 0 != ((Integer) ICBillFlag.FREE.value())
                    .compareTo((Integer) origVO.getFbillflag())) {
                throw new BusinessException(
                        nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("4008027_0",
                                "04008027-0329")/* @res "当前入库单编号：" */ + origVO.getVbillcode()
                                + nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID(
                                "4008027_0", "04008027-0362")/* @res "不是自由状态，不能修改" */);
            }
            origVO.setStatus(VOStatus.UPDATED);
            for (String attr : newVO.getAttributeNames()) {
                if (newVO.getAttributeValue(attr) == null) {
                    continue;
                }
                if (headProFields.contains(attr) && !newVO.getAttributeValue(attr)
                        .equals(origVO.getAttributeValue(attr))) {
                    throw new BusinessException(
                            nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID(
                                    "4008027_0", "04008027-0363")/* @res "表头字段：" */ + attr
                                    + nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID(
                                    "4008027_0", "04008027-0364")/* @res "不允许修改。" */);
                }
                origVO.setAttributeValue(attr, newVO.getAttributeValue(attr));
            }
            for (PurchaseInVO orivo : originBills) {
                PurchaseInBodyVO[] oribodys = orivo.getBodys();
                for (PurchaseInBodyVO oribody : oribodys) {
                    ICLocationVO[] locationVOs = oribody.getLocationVOs();
                    if (null != locationVOs) {
                        deleteLoc.put(oribody.getCgeneralbid(), locationVOs);
                    }
                }
            }
            if (vos[0].getBodys() != null) {
                Map<String, PurchaseInBodyVO> pkbs =
                        new HashMap<String, PurchaseInBodyVO>();
                for (PurchaseInBodyVO origBvo : purInVOs[0].getBodys()) {
                    origBvo.setStatus(VOStatus.UPDATED);
                    pkbs.put(origBvo.getCgeneralbid(), origBvo);
                }
                for (PurchaseInBodyVO newBvo : vos[0].getBodys()) {
                    PurchaseInBodyVO roigBvo = pkbs.get(newBvo.getCgeneralbid());
                    if (newBvo.getCgeneralbid() == null || roigBvo == null) {
                        throw new BusinessException(nc.vo.ml.NCLangRes4VoTransl
                                .getNCLangRes().getStrByID("4008027_0", "04008027-0382")/*
                         * @res
                         * "没有匹配到原始入库单表体信息，请检查数据的表体主键cgeneralbid。"
                         */);
                    }
                    for (String battr : newBvo.getAttributeNames()) {
                        if (newBvo.getAttributeValue(battr) == null) {
                            continue;
                        }
                        if (bodyProFields.contains(battr)
                                && !newBvo.getAttributeValue(battr)
                                .equals(roigBvo.getAttributeValue(battr))) {
                            throw new BusinessException(
                                    nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID(
                                            "4008027_0", "04008027-0366")/* @res "表体字段：" */ + battr
                                            + nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID(
                                            "4008027_0", "04008027-0364")/* @res "不允许修改。" */);
                        }
                        roigBvo.setAttributeValue(battr, newBvo.getAttributeValue(battr));
                        bfields.add(battr);
                    }
                    //设置货位序列号孙表,把原来的孙表删除，修改的货位置为新增
                    if (null != newBvo.getLocationVOs()) {
                        List<ICLocationVO> allloc = new ArrayList<ICLocationVO>();
                        if (null != deleteLoc && null != deleteLoc.get(roigBvo.getCgeneralbid())) {
                            for (ICLocationVO delloc : deleteLoc.get(roigBvo.getCgeneralbid())) {
                                delloc.setStatus(VOStatus.DELETED);
                                allloc.add(delloc);
                            }
                        }
                        for (ICLocationVO loc : newBvo.getLocationVOs()) {
                            loc.setStatus(VOStatus.NEW);
                            allloc.add(loc);
                        }
                        roigBvo.setLocationVOs(allloc.toArray(new ICLocationVO[allloc.size()]));
                    }
                }

            }
        }
        // 翻译货位
        ICAPILocationVOUtils.translate(purInVOs);
        // 其他数据填充
        new PurchaseInUpdateFillValue().setDefaultValue(purInVOs);
        BillMaintainTool<PurchaseInVO> tool = new BillMaintainTool<PurchaseInVO>(
                PurchaseInVO.class, ICBillType.PurchaseIn.getCode());
        tool.doBeforeInsert(purInVOs);
        return nc.bs.framework.common.NCLocator.getInstance()
                .lookup(nc.itf.ic.m45.self.IPurchaseInMaintain.class)
                .update(purInVOs, originBills);
    }

    @Override
    public void delete(PurchaseInVO[] vos) throws BusinessException {
        nc.bs.framework.common.NCLocator.getInstance()
                .lookup(nc.itf.ic.m45.self.IPurchaseInMaintain.class).delete(vos);

    }

    @Override
    public PurchaseInVO[] sign(PurchaseInVO[] vos) throws BusinessException {
        if (ArrayUtils.isEmpty(vos)) {
            return null;
        }
        for (PurchaseInVO aggvo : vos) {
            ICBillHeadVO parentVO = aggvo.getParentVO();
            if (parentVO.getFbillflag() == null
                    || 0 != ((Integer) ICBillFlag.FREE.value())
                    .compareTo((Integer) parentVO.getFbillflag())) {
                throw new BusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes()
                        .getStrByID("4008027_0", "04008027-0329")
                        /* @res "当前入库单编号：" */ + parentVO.getVbillcode()
                        + nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID(
                        "4008027_0", "04008027-0330")/* @res "不是自由状态，不能签字" */);
            }
            if (aggvo.getChildrenVO() != null && aggvo.getChildrenVO().length > 0) {
                if (aggvo.getChildrenVO()[0]
                        .getAttributeValue(ICPubMetaNameConst.NNUM) == null) {
                    throw new BusinessException(nc.vo.ml.NCLangRes4VoTransl
                            .getNCLangRes().getStrByID("4008027_0", "04008027-0329")
                            /* @res "当前入库单编号：" */ + parentVO.getVbillcode()
                            + nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID(
                            "4008027_0", "04008027-0331")/* @res "主数量为空，不能签字" */);
                }
            }
        }
        // 加载货位单品明细
        ICLocationUtil.loadLocationVOs(vos);

        return (PurchaseInVO[]) PfServiceScmUtil.processBatch("SIGN", "45", vos,
                null, null);
    }

    @Override
    public PurchaseInVO[] unSign(PurchaseInVO[] vos) throws BusinessException {
        if (ArrayUtils.isEmpty(vos)) {
            return null;
        }
        for (PurchaseInVO aggvo : vos) {
            ICBillHeadVO parentVO = aggvo.getParentVO();
            if (parentVO.getFbillflag() == null
                    || 0 != ((Integer) ICBillFlag.SIGN.value())
                    .compareTo((Integer) parentVO.getFbillflag())) {
                throw new BusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes()
                        .getStrByID("4008027_0", "04008027-0329")
                        /* @res "当前入库单编号：" */ + parentVO.getVbillcode()
                        + nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID(
                        "4008027_0", "04008027-0332")/* @res "不是签字状态，不能取消签字" */);
            }
        }
        return (PurchaseInVO[]) PfServiceScmUtil.processBatch("CANCELSIGN", "45",
                vos, null, null);
    }

}
