package nckd.jimin.jyyy.bd.task.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import kd.bos.basedata.service.BaseDataServiceImpl;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.entity.LocaleString;
import kd.bos.dataentity.metadata.dynamicobject.DynamicObjectType;
import kd.bos.db.DB;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.ext.fi.plugin.ArApConvert.util.EmptyUtils;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.basedata.BaseDataServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.util.StringUtils;
import nckd.jimin.jyyy.bd.common.oauth.FanWeiUtils;
import nckd.jimin.jyyy.bd.task.SynSapService;
import nckd.jimin.jyyy.bd.task.SyncSapUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

public class SynSapServiceImpl implements SynSapService {

    protected static final Long DEFAULT_ORG_ID = 100000L;
    private static final Log logger = LogFactory.getLog(SynSapServiceImpl.class);

    /**
     * 同步成本中心
     *
     * @param companyCode
     * @return
     */
    @Override
    public Map<String, String> synCostCenterForSap(String companyCode) {
        Map<String, String> result = new HashMap<>();
        logger.info("同步SAP主数据_成本");
        String data = SyncSapUtils.getCostCenterData(companyCode);
        String url = "costcenter";
        logger.info("同步SAP主数据_成本，参数：" + data);
        String response = SyncSapUtils.postDataToSAP(url, data);
        if (StringUtils.isEmpty(response)) {
            result.put("code", "300");
            result.put("msg", "同步SAP主数据_成本，同步失败");
            return result;
        }
        JSONObject rData = JSONObject.parseObject(response);
        String etype = rData.getString("E_TYPE");

        if (!"S".equals(etype)) {
            result.put("code", "301");
            result.put("msg", "同步SAP主数据_成本，E_TYPE:" + etype + "，错误信息：" + rData.getString("E_MESSGE"));
            return result;
        }

        JSONObject rEtItem = rData.getJSONObject("ET_ITEM");
        if (rEtItem == null) {
            result.put("code", "302");
            result.put("msg", "同步SAP主数据_成本，ET_ITEM参数为空");
            return result;
        }

        JSONArray rItemArray = rEtItem.getJSONArray("item");
        if (rItemArray == null) {
            result.put("code", "303");
            result.put("msg", "同步SAP主数据_成本，item参数为空");
            return result;
        }

        List<String> costNumList = new ArrayList<String>();
        for (int i = 0; i < rItemArray.size(); ++i) {
            JSONObject item = rItemArray.getJSONObject(i);
            String number = item.getString("KOSTL");
            costNumList.add(number);
        }
        //取组织对象
        QFilter qf = new QFilter("number", QCP.equals, companyCode);
        DynamicObject companyDyn = BusinessDataServiceHelper.loadSingle("bos_org", new QFilter[]{qf});

        //取上级
        DynamicObject parent = BusinessDataServiceHelper.loadSingle("bos_costcenter", new QFilter[]{new QFilter("number", QCP.equals, companyCode)});

        QFilter qFilter = new QFilter("number", QCP.in, costNumList);
        List<Object> listIDs = QueryServiceHelper.queryPrimaryKeys("bos_costcenter",new QFilter[]{qFilter}, null, Integer.MAX_VALUE);
        DynamicObject costDyn =  BusinessDataServiceHelper.newDynamicObject("bos_costcenter");
        DynamicObject[] costDyns = BusinessDataServiceHelper.load(listIDs.toArray(),costDyn.getDynamicObjectType());
        //DynamicObject[] costDyns = BusinessDataServiceHelper.load("bos_costcenter", "id,masterid,parent,number,name,accountorg,orgduty,status,enable", new QFilter[]{qFilter});
        Map<String, DynamicObject> costMap =
                Arrays.stream(costDyns)
                        .collect(Collectors.toMap(
                                detail -> detail.getString("number"),
                                detail -> detail, // 整个 DynamicObject 作为 value
                                (existing, replacement) -> existing // 保留前面的值
                        ));
        ArrayList<DynamicObject> costList = new ArrayList<>();
        StringBuilder err = new StringBuilder();


        SimpleDateFormat shortformat = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat longformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String curDateStr = shortformat.format(new Date());
        String suffix = " 00:00:00";

        Date curDate;
        try {
            curDate = longformat.parse(curDateStr + suffix);
        } catch (ParseException e) {
            result.put("code", "303");
            result.put("msg", "当前日期格式异常");
            return result;
        }

        for (int i = 0; i < rItemArray.size(); ++i) {
            JSONObject item = rItemArray.getJSONObject(i);
            String number = item.getString("KOSTL");

            String name = item.getString("KTEXT");
            if (i == 0 && (StringUtils.isEmpty(number) || StringUtils.isEmpty(name))) {
                continue;
            }
            if (StringUtils.isEmpty(number) || StringUtils.isEmpty(name)) {
                err.append("/n 存在项目编号或名称为空， " + number + name);
                continue;
            }

            //生效截止时间
            String endDateStr = item.getString("DATBI");
            Date endDate = curDate;
            if(StringUtils.isNotEmpty(endDateStr) && !"0000-00-00".equals(endDateStr)) {
                try {
                    endDate = longformat.parse(endDateStr + suffix);
                } catch (ParseException e) {
                    result.put("code", "303");
                    result.put("msg", "到期日期格式异常");
                    return result;
                }
            }

            if (EmptyUtils.isNotEmpty(number)) {
                DynamicObject dyn = costMap.get(number);
                if (dyn == null) {
                    dyn = BusinessDataServiceHelper.newDynamicObject("bos_costcenter");
                    long Id = DB.genLongId("t_bos_costcenter");
                    dyn.set("id", Id);
                    dyn.set("number", number); // 编号
                    dyn.set("accountorg", companyDyn);//核算组织
                    String orgduty = item.getString("KTEXT");
                    if (EmptyUtils.isNotEmpty(orgduty)) {

                        String orgdutyValue = orgduty.substring(orgduty.length() - 1);

                        switch (orgdutyValue) {
                            case "V"://销售
                                dyn.set("orgduty", "3");
                                break;
                            case "L"://管理
                                dyn.set("orgduty", "1");
                                break;
                            case "F"://制造
                                dyn.set("orgduty", "4");
                                break;
                            case "E"://研发
                                dyn.set("orgduty", "2");
                                break;
                            default://其他
                                dyn.set("orgduty", "5");
                                break;
                        }

                    }
                }
                dyn.set("name", item.getString("KTEXT"));////项目名称
                dyn.set("status", "C");   ///单据状态
                dyn.set("enable", "1");  //使用状态

                //如果生效截止日期小于当前时间，则禁用
                if(endDate.compareTo(curDate) < 0) {
                    dyn.set("enable", "0");  //使用状态
                }

                if (EmptyUtils.isNotEmpty(parent)) {
                    dyn.set("parent", parent);
                }
                logger.info("同步SAP主数据_成本，id：" + dyn.getLong("id") + "  -->" + Long.valueOf(dyn.getString("id")));
                dyn.set("masterid", Long.valueOf(dyn.getString("id")));
                costList.add(dyn);
            }
        }

        if (costList.size() > 0) {
            DynamicObject[] saveDynamicObject = costList.toArray(new DynamicObject[costList.size()]);
            Object[] save = SaveServiceHelper.save(saveDynamicObject);
            int length = save.length;
            logger.info("同步[成本]完成，本次新增数量：{}," + err, length);
            result.put("code", "200");
            result.put("msg", "同步SAP主数据_成本，执行成功，本次同步数量" + length + err);
        } else {
            result.put("code", "304");
            result.put("msg", "同步SAP主数据_没有数据");
        }

        return result;
    }

    /**
     * 同步SAP主数据中的项目信息
     * <p>
     * 本方法负责从SAP系统同步项目相关的主数据，处理并保存到当前系统中
     * 它首先从SAP获取项目数据，然后解析这些数据，并与系统中已存在的项目信息进行对比和更新
     * 如果项目在系统中不存在，则会创建新的项目记录；如果存在，则更新项目信息
     * <p>
     * 1、根据 SAP 项目编码判断层级
     * 编码中的2010、2060 代表公司  1级项目（编码无点）按全局共享，2级项目阶段，按02、.03判断私分配隔（私有）
     * 需要代码自动判断创建1级项目
     * 注意需要单独处理项目t_bd_project_u表数据，否则不能在界面查询出来
     *
     * @param companyCode 公司代码，用于过滤特定公司的项目信息
     * @return 返回一个包含同步结果的Map，包括状态码（code）和消息（msg）
     */
    @Override
    public Map<String, String> synProjectForSap(String companyCode) {
        BaseDataServiceImpl baseDataService = new BaseDataServiceImpl();
        Map<String, String> result = new HashMap<>();
        logger.info("同步SAP主数据_项目");
        String data = SyncSapUtils.getProjectData(companyCode);
        String url = "project";
        logger.info("同步SAP主数据_项目，参数：" + data);
        String response = SyncSapUtils.postDataToSAP(url, data);

        if (StringUtils.isEmpty(response)) {
            result.put("code", "300");
            result.put("msg", "同步SAP主数据_项目，同步失败");
            return result;
        }
        JSONObject rData = JSONObject.parseObject(response);

        String etype = rData.getString("E_TYPE");

        if (!"S".equals(etype)) {
            result.put("code", "301");
            result.put("msg", "同步SAP主数据_项目，错误信息：" + rData.getString("E_MESSGE"));
            logger.info("同步SAP主数据_项目，参数：E_TYPE:" + etype + "，错误信息：" + rData.getString("E_MESSGE"));
            return result;
        }

        JSONObject rEtItem = rData.getJSONObject("ET_ITEM");
        if (rEtItem == null) {
            result.put("code", "302");
            result.put("msg", "同步SAP主数据_项目，ET_ITEM参数为空");
            return result;
        }

        JSONArray rItemArray = rEtItem.getJSONArray("item");
        if (rItemArray == null) {
            result.put("code", "303");
            result.put("msg", "同步SAP主数据_项目，item参数为空");
            return result;
        }

        List<String> projectNumList = new ArrayList<String>();
        for (int i = 0; i < rItemArray.size(); ++i) {
            JSONObject item = rItemArray.getJSONObject(i);
            String number = item.getString("POSID");
            projectNumList.add(number);
            //String parent = SyncSapUtils.getProjectNumberForParent(number);
            //projectNumList.add(parent);
        }
        //取组织对象
        QFilter qf = new QFilter("number", QCP.equals, companyCode);
        DynamicObject companyDyn = BusinessDataServiceHelper.loadSingle("bos_org", new QFilter[]{qf});

        QFilter qFilter = new QFilter("number", QCP.in, projectNumList);
        QFilter qFilter1 = new QFilter("org.number", QCP.equals, companyCode);

        /**
         * 当存在对象与新增对象同时Save时，会报错，通过以下方式解决
         * 先用QueryServiceHelper查询出id，再用BusinessDataServiceHelper。这样就与新增的数据包保持一致了
         */
        List<Object> listIDs = QueryServiceHelper.queryPrimaryKeys("bd_project",new QFilter[]{qFilter, qFilter1}, null, Integer.MAX_VALUE);
        DynamicObject projectDyn =  BusinessDataServiceHelper.newDynamicObject("bd_project");
        DynamicObject[] dyns = BusinessDataServiceHelper.load(listIDs.toArray(),projectDyn.getDynamicObjectType());
        //DynamicObject[] dyns = BusinessDataServiceHelper.load("bd_project", "id,number,name,fullname,parent,masterid,proleader,org,useorg,createorg,group,status,ctrlstrategy,level,isleaf,department,prostatus,enable", new QFilter[]{qFilter, qFilter1});

        Map<String, DynamicObject> projectMap =
                Arrays.stream(dyns)
                        .collect(Collectors.toMap(
                                detail -> detail.getString("number"),
                                detail -> detail, // 整个 DynamicObject 作为 value
                                (existing, replacement) -> existing // 保留前面的值
                        ));

        List<DynamicObject> projectList = new ArrayList<>();
        Map<String, DynamicObject> parentMap = new HashMap<>();
        List<Object[]> useorgList = new ArrayList<>();
        StringBuilder err = new StringBuilder();

        for (int i = 0; i < rItemArray.size(); ++i) {
            JSONObject item = rItemArray.getJSONObject(i);
            String number = item.getString("POSID");
            String name = item.getString("POST1");
            if (StringUtils.isEmpty(number) || StringUtils.isEmpty(name)) {
                err.append("  \n存在项目编号或名称为空， " + number + name);
                continue;
            }

//            if(!number.contains("AD20220999")) continue;    ////用于测试

            String proleader = item.getString("USR03");
            String department = item.getString("DEPARTMENT");
            String typeStr = item.getString("ZBY2");
            String type = SyncSapUtils.getType(typeStr);
            String billstatus = item.getString("STATUS");
            DynamicObject proleaderDyn = null;
            DynamicObject departmentDyn = null;
            DynamicObject typeDyn = null;
            DynamicObject projectStatusDyn = null;
            if (StringUtils.isNotEmpty(proleader)) {
                QFilter qf1 = new QFilter("number", QCP.equals, proleader);
                proleaderDyn = BusinessDataServiceHelper.loadSingle("bos_user", new QFilter[]{qf1});
            }
            if (StringUtils.isNotEmpty(department)) {
                QFilter qf1 = new QFilter("number", QCP.equals, department);
                departmentDyn = BusinessDataServiceHelper.loadSingle("bos_org", new QFilter[]{qf1});
            }
            if (StringUtils.isNotEmpty(type)) {
                QFilter qf1 = new QFilter("number", QCP.equals, type);
                typeDyn = BusinessDataServiceHelper.loadSingle("bd_projectkind", new QFilter[]{qf1});
            }
            if (StringUtils.isNotEmpty(billstatus)) {
                QFilter qf1 = new QFilter("nckd_sapprojstatus", QCP.equals, billstatus);
                projectStatusDyn = BusinessDataServiceHelper.loadSingle("bd_projectstatus", new QFilter[]{qf1});
            }
            QFilter qf2 = new QFilter("number", QCP.equals, "SAP");
            DynamicObject srcSysDyn = BusinessDataServiceHelper.loadSingle("bos_devportal_bizcloud", new QFilter[]{qf2});

            /*
             * 处理一级项目，来自于项目编码前段编码  BD20200303.2010.07 ，BD20200303为一级项目编码
             * */
            DynamicObject parentDyn = null;
            String parent = SyncSapUtils.getProjectNumberForParent(number);
            if (StringUtils.isNotEmpty(parent) ) {
                QFilter qf1 = new QFilter("number", QCP.equals, parent);
                DynamicObject parentDyn1 = BusinessDataServiceHelper.loadSingle("bd_project", new QFilter[]{qf1});
                DynamicObject parentDyn2 = parentMap.get(parent);  //会有多个相同的父项目，需要去重
                if(parentDyn1 != null){
                    parentDyn = parentDyn1;
                }else{
                    parentDyn = parentDyn2;
                }
                if (parentDyn == null) {
                    parentDyn = BusinessDataServiceHelper.newDynamicObject("bd_project");
                    long Id = DB.genLongId("t_bd_project");
                    parentDyn.set("id", Id);
                    parentDyn.set("masterid", Id);
                    parentDyn.set("number", parent); // 编号
                    parentDyn.set("org", DEFAULT_ORG_ID);  //一级项目放在顶层组织下
                    parentDyn.set("createorg", DEFAULT_ORG_ID);  //一级项目放在顶层组织下
                    if (EmptyUtils.isNotEmpty(typeDyn)) {
                        parentDyn.set("group", typeDyn);  ///项目分类
                    }
                    parentDyn.set("level", 1);
                    parentDyn.set("isleaf", 0);
                    parentDyn.set("status", "C");        ///单据状态
                    parentDyn.set("ctrlstrategy", "5");  //控制策略  自由分配 2 全局共享 5  私有 7
                    parentDyn.set("enable", "1");        //使用状态
                    // parentDyn.set("prostatus", "PASS_S"); //项目状态 PASS通过
                    parentDyn.set("name", parent);
                    parentDyn.set("fullname", parent);
                    if (EmptyUtils.isNotEmpty(proleaderDyn)) {
                        parentDyn.set("proleader", proleaderDyn);
                    }
                    if (EmptyUtils.isNotEmpty(departmentDyn)) {
                        parentDyn.set("department", departmentDyn);
                    }
                    if (EmptyUtils.isNotEmpty(projectStatusDyn)) {
                        parentDyn.set("prostatus", projectStatusDyn);
                    }
                    if (EmptyUtils.isNotEmpty(srcSysDyn)) {
                        parentDyn.set("systemtypebase", srcSysDyn);
                    }
                    parentMap.put(parent, parentDyn);
                }else{
                    if (EmptyUtils.isNotEmpty(typeDyn)) {
                        parentDyn.set("group", typeDyn);  ///项目分类
                    }
                    if (EmptyUtils.isNotEmpty(proleaderDyn)) {
                        parentDyn.set("proleader", proleaderDyn);
                    }
                    if (EmptyUtils.isNotEmpty(departmentDyn)) {
                        parentDyn.set("department", departmentDyn);
                    }
                    if (EmptyUtils.isNotEmpty(projectStatusDyn)) {
                        parentDyn.set("prostatus", projectStatusDyn);
                    }
                    parentMap.put(parent, parentDyn);
                }
            }

            DynamicObject dyn = projectMap.get(number);
            if (dyn == null) {

                /***
                 * 处理二级项目，如果项目编码中包含点，则需要处理上级项目
                 */
                dyn = BusinessDataServiceHelper.newDynamicObject("bd_project");
                long Id = DB.genLongId("t_bd_project");
                dyn.set("id", Id);
                dyn.set("masterid", Id);
                if (EmptyUtils.isNotEmpty(parentDyn)) {
                    dyn.set("parent", parentDyn.getPkValue());
                }
                dyn.set("number", number); // 编号
                dyn.set("org", companyDyn.getPkValue());
                dyn.set("level", 2);
                dyn.set("isleaf", 1);
                dyn.set("createorg", companyDyn.getPkValue());
                dyn.set("useorg", companyDyn.getPkValue());
                if (EmptyUtils.isNotEmpty(typeDyn)) {
                    dyn.set("group", typeDyn.getPkValue());  ///项目分类
                }
                dyn.set("status", "C");        ///单据状态
                dyn.set("ctrlstrategy", "7");  //控制策略  自由分配 2 全局共享 5  私有 7
                dyn.set("enable", "1");        //使用状态
                //dyn.set("prostatus", "PASS_S"); //项目状态 PASS通过

                /***
                 * 当控制策略为自由分配和私有时，需要单独处理项目t_bd_project_u表数据，否则不能在界面查询出来
                 */
                Object[] odjs = new Object[]{
                        dyn.get("id"),
                        dyn.get("useorg")
                };
                useorgList.add(odjs);
            }
            dyn.set("name", item.getString("POST1"));
            dyn.set("fullname", item.getString("POST1"));
            dyn.set("nckd_zby3", item.getString("ZBY3"));
            if (EmptyUtils.isNotEmpty(proleaderDyn)) {
                dyn.set("proleader", proleaderDyn.getPkValue());
            }
            if (EmptyUtils.isNotEmpty(typeDyn)) {
                dyn.set("group", typeDyn.getPkValue());  ///项目分类
            }
            if (EmptyUtils.isNotEmpty(departmentDyn)) {
                dyn.set("department", departmentDyn.getPkValue());
            }
            if (EmptyUtils.isNotEmpty(projectStatusDyn)) {
                dyn.set("prostatus", projectStatusDyn.getPkValue());
            }
            if (EmptyUtils.isNotEmpty(srcSysDyn)) {
                dyn.set("systemtypebase", srcSysDyn.getPkValue());
            }

            dyn.set("nckd_datasource", "sap");

            projectList.add(dyn);
        }

        /***
         * 添加项目上级
         */
        for (Map.Entry<String, DynamicObject> entry : parentMap.entrySet()) {
            DynamicObject parentdyn = entry.getValue();
            projectList.add(parentdyn);
        }

        /**
         * 保存项目
         */
        if (projectList.size() > 0) {
            // 将saveList转为数组
            DynamicObject[] saveDynamicObject = projectList.toArray(new DynamicObject[projectList.size()]);
            Object[] save = SaveServiceHelper.save(saveDynamicObject);
            int length = save.length;
            logger.info("同步[项目]完成，本次新增数量：{}," + err, length);
            result.put("code", "200");
            result.put("msg", "同步SAP主数据_项目，执行成功，本次同步数量" + length + err);
        } else {
            result.put("code", "304");
            result.put("msg", "同步SAP主数据_错误," + err);
        }
        /***
         * 需要单独处理项目t_bd_project_u表数据，否则不能在界面查询出来
         */
        if (useorgList.size() > 0) {
            baseDataService.savePrivateBaseDataUseRange("bd_project", useorgList);
            logger.info("同步[项目]完成，t_bd_project_u表");
        }
        return result;
    }

    @Override
    public Map<String, String> synAccountViewForSap(String companyCode) {
        Map<String, String> result = new HashMap<>();

        String data = SyncSapUtils.getAccountViewData(companyCode);
        String url = "account";
        String response = SyncSapUtils.postDataToSAP(url, data);

        if (StringUtils.isEmpty(response)) {
            result.put("code", "300");
            result.put("msg", "同步失败");
            return result;
        }
        JSONObject rData = JSONObject.parseObject(response);

        String etype = rData.getString("E_TYPE");

        if (!"S".equals(etype)) {
            result.put("code", "301");
            result.put("msg", "E_TYPE:" + etype + "，错误信息：" + rData.getString("E_MESSGE"));
            return result;
        }

        JSONObject rEtItem = rData.getJSONObject("ET_ITEM");
        if (rEtItem == null) {
            result.put("code", "302");
            result.put("msg", "ET_ITEM参数为空");
            return result;
        }

        JSONArray rItemArray = rEtItem.getJSONArray("item");
        if (rItemArray == null) {
            result.put("code", "303");
            result.put("msg", "item参数为空");
            return result;
        }


        return result;
    }

    /**
     * 同步OA主数据中的讲者信息
     *
     * <p>本方法负责从OA系统同步讲者相关的主数据，处理并保存到当前系统中。
     * 它首先调用 FanWeiUtils.getFanWeiToken 获取泛微接口的访问令牌，并请求讲者数据，
     * 然后解析这些数据，并与系统中已存在的讲者信息进行对比和更新。
     * 如果讲者在系统中不存在，则会创建新的讲者记录；如果存在，则更新相关信息。</p>
     *
     * <p><b>关键流程如下：</b>
     * <ul>
     *     <li>调用 getFanWeiToken 方法获取访问 Token</li>
     *     <li>请求并解析 OA 接口返回的讲者数据</li>
     *     <li>遍历讲者数据，提取身份证号、姓名等核心字段</li>
     *     <li>根据身份证号判断是否为新讲者，如是则新建 DynamicObject，否则更新已有记录</li>
     *     <li>设置讲者的相关属性，包括医院、单位、领域、评定级别等扩展信息</li>
     *     <li>批量保存讲者数据，并返回同步结果</li>
     * </ul>
     * </p>
     *
     * @return 返回一个包含同步结果的Map，其中：
     *         <ul>
     *             <li>"code": 状态码（200 表示成功，其他表示失败）</li>
     *             <li>"msg": 同步结果描述信息</li>
     *         </ul>
     */
    @Override
    public Map<String, String> synSpeakerForOA() {
        Map<String, String> result = new HashMap<>();
        logger.info("同步OA主数据_讲者");
        String response = FanWeiUtils.getFanWeiToken("speaker");
        //logger.info("返回的数据："+response);
        if(StringUtils.isEmpty(response)){
            result.put("code", "300");
            result.put("msg", "同步OA主数据_讲者失败");
            return result;
        }
        JSONObject rData = JSONObject.parseObject(response);
        JSONObject datajson=rData.getJSONObject("datajson");
        if(datajson==null){
            result.put("code", "301");
            result.put("msg", "同步OA主数据_讲者,datajson参数为空");
        }
        Boolean status  = datajson.getBoolean("status");
        if(status){
            result.put("code", "302");
            result.put("msg", "同步OA主数据_讲者,数据无效");
        }

        JSONArray datas=datajson.getJSONArray("datas");
        if(datas==null){
            result.put("code", "303");
            result.put("msg", "同步OA主数据_讲者,datas参数为空");
        }
        //获取所有讲者身份证号
        List<String> speakerIdList=new ArrayList<>();
        for(int i=0;i<datas.size();i++){
            JSONObject item=datas.getJSONObject(i);
            JSONObject mainTable=item.getJSONObject("mainTable");
            String sfzh=mainTable.getString("sfzh");
            speakerIdList.add(sfzh);
        }
        QFilter qFilter = new QFilter("number", QCP.in, speakerIdList);
        List<Object> listIDs = QueryServiceHelper.queryPrimaryKeys("nckd_speaker",new QFilter[]{qFilter}, null, Integer.MAX_VALUE);
        DynamicObject speakerDyn =  BusinessDataServiceHelper.newDynamicObject("nckd_speaker");
        DynamicObject[] speakerDyns = BusinessDataServiceHelper.load(listIDs.toArray(),speakerDyn.getDynamicObjectType());

        //QFilter qFilter = new QFilter("number", QCP.in, speakerIdList);
        //DynamicObject[] speakerDyns = BusinessDataServiceHelper.load("nckd_speaker", "id,number,name,status,creator,enable,nckd_pdjb,nckd_zlly,nckd_shdw,nckd_rzyy", new QFilter[]{qFilter});
        Map<String, DynamicObject> speakerMap =
                Arrays.stream(speakerDyns)
                        .collect(Collectors.toMap(
                                detail -> detail.getString("number"),
                                detail -> detail, // 整个 DynamicObject 作为 value
                                (existing, replacement) -> existing // 保留前面的值
                        ));
        ArrayList<DynamicObject> speakerDynList = new ArrayList<>();
        StringBuilder err = new StringBuilder();

        for(int i=0;i<datas.size();i++){
            JSONObject item=datas.getJSONObject(i);
            JSONObject mainTable=item.getJSONObject("mainTable");
            //身份证号
            String  sfzh=mainTable.getString("sfzh");
            if(EmptyUtils.isEmpty(sfzh)){
                err.append("第"+i+"条数据身份证号为空,");
                continue;
            }
            //姓名
            String zjxm=mainTable.getString("zjxm");
            if(EmptyUtils.isEmpty(zjxm)){
                err.append("第"+i+"条数据姓名为空,");
                continue;
            }
            //任职医院
            String rzyy=mainTable.getString("rzyy");
            //社会单位
            String shdw=mainTable.getString("shdw");
            //治疗领域
            String zlly=mainTable.getString("zlly");
            //专家评定级别  0:院士级 1:国家级 2:区域/省级 3:城市级 4:普通级
            String zjpdjb=mainTable.getString("zjpdjb");
            //数据状态 1表示正常 单据
            String data_status=mainTable.getString("data_status");
            //创建人
            String creator=mainTable.getString("creator");
            //创建时间
            //主数据内码
            if(EmptyUtils.isNotEmpty(sfzh)){
                DynamicObject dyn=speakerMap.get(sfzh);
                if(dyn==null){
                    dyn=BusinessDataServiceHelper.newDynamicObject("nckd_speaker");
                    dyn.set("number", sfzh);
                }
                dyn.set("name",zjxm);
                dyn.set("nckd_rzyy",rzyy);
                dyn.set("nckd_shdw",shdw);
                dyn.set("nckd_zlly",zlly);
                if(EmptyUtils.isNotEmpty(zjpdjb)){
                    switch (zjpdjb){
                        case "0":
                            dyn.set("nckd_pdjb","院士级");
                            break;
                        case "1":
                            dyn.set("nckd_pdjb","国家级");
                            break;
                        case "2":
                            dyn.set("nckd_pdjb","区域/省级");
                            break;
                        case "3":
                            dyn.set("nckd_pdjb","城市级");
                            break;
                        case "4":
                            dyn.set("nckd_pdjb","普通级");
                            break;
                        default:
                            dyn.set("nckd_pdjb",zjpdjb);
                            break;
                    }
                }
                //数据状态
                dyn.set("status","C"); //接口值 没有用，直接给审核状态
                //creator创建人
                dyn.set("creator",creator);
                //使用状态
                dyn.set("enable", "1");
                speakerDynList.add(dyn);
            }
        }
        if(speakerDynList.size()>0) {
            DynamicObject[] saveDynamicObject = speakerDynList.toArray(new DynamicObject[speakerDynList.size()]);
            Object[] save = SaveServiceHelper.save(saveDynamicObject);
            int length = save.length;
            logger.info("同步[讲者]完成，本次新增数量：{},"+err, length);
            result.put("code", "200");
            result.put("msg", "同步OA主数据_讲者，执行成功，本次同步数量"+length+err);
        }else{
            result.put("code", "304");
            result.put("msg", "同步OA主数据_没有数据");
        }
        return result;
    }


    /**
     * 同步会计科目
     * @param companyCode
     * @return
     */
    public Map<String, String> synAccountForSap(String companyCode) {
        Map<String, String> result = new HashMap<>();
        logger.info("同步SAP主数据_会计科目");

        String data = SyncSapUtils.getAccountData(companyCode);
        String url = "account";

        logger.info("同步SAP主数据_会计科目，参数：" + data);

        String response = SyncSapUtils.postDataToSAP(url, data);
        if (StringUtils.isEmpty(response)) {
            result.put("code", "300");
            result.put("msg", "同步SAP主数据_会计科目，同步失败");
            return result;
        }
        JSONObject rData = JSONObject.parseObject(response);
        String etype = rData.getString("E_TYPE");

        if (!"S".equals(etype)) {
            result.put("code", "301");
            result.put("msg", "同步SAP主数据_会计科目，E_TYPE:" + etype + "，错误信息：" + rData.getString("E_MESSGE"));
            return result;
        }

        JSONObject rEtItem = rData.getJSONObject("ET_ITEM");
        if (rEtItem == null) {
            result.put("code", "302");
            result.put("msg", "同步SAP主数据_会计科目，ET_ITEM参数为空");
            return result;
        }

        JSONArray rItemArray = rEtItem.getJSONArray("item");
        if (rItemArray == null) {
            result.put("code", "303");
            result.put("msg", "同步SAP主数据_会计科目，item参数为空");
            return result;
        }

        String entityAccount = "bd_accountview";

        //先遍历出所有的会计科目编码
        List<String> costNumList = rItemArray.stream().map(JSONObject.class::cast)
                                                        .filter(json -> json.getString("SAKNR").length() > 4)
                                                        .map(json -> json.getString("SAKNR"))
                                                        .collect(Collectors.toList());

        List<String> parentList = rItemArray.stream().map(JSONObject.class::cast)
                .filter(json -> json.getString("SAKNR").length() > 4)
                .map(json -> json.getString("SAKNR").substring(0, 4))
                .collect(Collectors.toList());

        List<String> parentNumList = parentList.stream().distinct().collect(Collectors.toList());


        DynamicObject accountDyn =  BusinessDataServiceHelper.newDynamicObject(entityAccount);

        QFilter qFilter = new QFilter("number", QCP.in, costNumList);
        qFilter.and(new QFilter("accounttable.number", QCP.equals, "0001"));

        List<Object> listIDs = QueryServiceHelper.queryPrimaryKeys(entityAccount, new QFilter[]{qFilter}, null, Integer.MAX_VALUE);

        DynamicObject[] accountDyns = BusinessDataServiceHelper.load(listIDs.toArray(), accountDyn.getDynamicObjectType());
        Map<String, DynamicObject> accountMaps = Arrays.stream(accountDyns)
                                                            .collect(Collectors.toMap(
                                                                    detail -> detail.getString("number"),
                                                                    detail -> detail, // 整个 DynamicObject 作为 value
                                                                    (existing, replacement) -> existing // 保留前面的值
                                                            ));

        qFilter = new QFilter("number", QCP.in, parentNumList);
        qFilter.and(new QFilter("accounttable.number", QCP.equals, "0001"));

        listIDs = QueryServiceHelper.queryPrimaryKeys(entityAccount, new QFilter[]{qFilter}, null, Integer.MAX_VALUE);
        DynamicObject[] parentDyns = BusinessDataServiceHelper.load(listIDs.toArray(), accountDyn.getDynamicObjectType());
        Map<String, DynamicObject> parentMaps = Arrays.stream(parentDyns)
                .collect(Collectors.toMap(
                        detail -> detail.getString("number"),
                        detail -> detail, // 整个 DynamicObject 作为 value
                        (existing, replacement) -> existing // 保留前面的值
                ));


        StringBuilder err = new StringBuilder();
        SimpleDateFormat shortformat = new SimpleDateFormat("yyyy-MM-dd");
        List<DynamicObject> accountList = new ArrayList<>();

        RequestContext rc = RequestContext.get();
        DynamicObject user = BusinessDataServiceHelper.loadSingle(rc.getCurrUserId(), "bos_user");

        QFilter qf = new QFilter("number", QCP.equals, companyCode);
        DynamicObject companyDyn = BusinessDataServiceHelper.loadSingle("bos_org", new QFilter[]{qf});

        List<Long> dataIds = new ArrayList();

        for (int i = 0; i < rItemArray.size(); ++i) {
            JSONObject item = rItemArray.getJSONObject(i);
            String number = item.getString("SAKNR");

            String name = item.getString("TXT50");
            if (i == 0 && (StringUtils.isEmpty(number) || StringUtils.isEmpty(name))) {
                continue;
            }

            if (StringUtils.isEmpty(number) || StringUtils.isEmpty(name)) {
                err.append("/n 存在编号或名称为空， " + number + name);
                continue;
            }

            if (number.length() <= 4) {
                err.append("/n 一级会计科目不做同步， " + number + name);
                continue;
            }

//            //测试
//            if(!"1001010000".equals(number)){
//                continue;
//            }
//            number = "1001010052";

            //上级科目编码
            String parentNumber = number.substring(0, 4);
            DynamicObject parent = parentMaps.get(parentNumber);
            if(parent == null){
                err.append("/n 一级会计科目在星瀚中不存在， " + number + name);
                continue;
            }

            String sDateStr = item.getString("ERDAT");
            Date sDate;
            Date eDate;
            try {
                sDate = shortformat.parse("1900-01-01");
                eDate = shortformat.parse("2999-12-31");

                if(StringUtils.isEmpty(sDateStr)){
                    sDate = shortformat.parse(sDateStr);
                }
            } catch (ParseException e) {
                result.put("code", "303");
                result.put("msg", "当前日期格式异常");
                return result;
            }

            DynamicObject accountInfo = accountMaps.get(number);
            if (accountInfo == null) {
                long Id = DB.genLongId("T_BD_Account");
                accountInfo = BusinessDataServiceHelper.newDynamicObject(entityAccount);

                //基本信息
                accountInfo.set("id", Id);
                accountInfo.set("number", number);//编号
                accountInfo.set("startdate", sDate);//版本化日期
                accountInfo.set("enddate", eDate);//失效日期
                accountInfo.set("parent", parent);//上级科目
                accountInfo.set("creator", user);
                accountInfo.set("createorg", parent.getDynamicObject("createorg"));//创建组织
                accountInfo.set("org", parent.getDynamicObject("org"));//创建组织
                accountInfo.set("useorg", parent.getDynamicObject("createorg"));
                accountInfo.set("srccreateorg", parent.getDynamicObject("srccreateorg"));//创建组织
                accountInfo.set("longnumber", parent.getString("number") + "_" + number);
                accountInfo.set("fullname", new LocaleString(parent.getString("name") + "_" + name));

                accountInfo.set("accounttable", parent.getDynamicObject("accounttable"));//科目表
                accountInfo.set("ctrlstrategy", parent.getString("ctrlstrategy"));//控制策略，默认逐级分配
                accountInfo.set("accounttype", parent.getDynamicObject("accounttype"));//科目类型
                accountInfo.set("pltype", parent.getString("pltype"));//损益类型
                accountInfo.set("dc", parent.getString("dc"));//余额方向
                accountInfo.set("level", 2);//级次

                //控制信息
                accountInfo.set("accrualdirection", parent.getString("accrualdirection"));//科目录入方向控制
                accountInfo.set("control", parent.getString("control"));//受控系统
                accountInfo.set("orgcontrollevel", "2");//控制级次
                accountInfo.set("isallowca", parent.getBoolean("isallowca"));//允许公司增加下级科目
                accountInfo.set("ismanual", parent.getBoolean("ismanual"));//允许公司增加下级科目

                //科目属性
                accountInfo.set("iscash", parent.getBoolean("iscash"));//现金科目
                accountInfo.set("isbank", parent.getBoolean("isbank"));//银行科目
                accountInfo.set("iscashequivalent", parent.getBoolean("iscashequivalent"));//现金等价物
                accountInfo.set("isjournal", parent.getBoolean("isjournal"));//登日记账
                accountInfo.set("acnotice", parent.getBoolean("acnotice"));//往来通知
                accountInfo.set("bw", parent.getBoolean("bw"));//表外科目
                accountInfo.set("ischangecurrency", parent.getBoolean("ischangecurrency"));//期末调汇
                accountInfo.set("isqty", parent.getBoolean("isqty"));//数量核算
                accountInfo.set("measureunitgroup", parent.getDynamicObject("measureunitgroup"));//计量单位分组
                accountInfo.set("measureunit", parent.getDynamicObject("measureunit"));//计量单位
                accountInfo.set("accheck", parent.getBoolean("accheck"));//往来核算
                accountInfo.set("isassist", parent.getBoolean("isassist"));//是否包含核算项目

                //核算维度
                DynamicObjectCollection assgrpEntrys = accountInfo.getDynamicObjectCollection("checkitementry");

                //上级科目核算维度
                List<String> parentItemList = new ArrayList<String>();
                DynamicObjectCollection parentEntrys = parent.getDynamicObjectCollection("checkitementry");
                if(parentEntrys.size() > 0){
                    for(DynamicObject parentEntry : parentEntrys){
                        DynamicObjectType assgrpType = assgrpEntrys.getDynamicObjectType();

                        DynamicObject asstrp = new DynamicObject(assgrpType);
                        asstrp.set("asstactitem", parentEntry.getDynamicObject("asstactitem"));//核算维度
                        asstrp.set("isrequire", parentEntry.getBoolean("isrequire"));//必录
                        asstrp.set("isdetail", parentEntry.getBoolean("isdetail"));//明细
                        asstrp.set("enaccheck", parentEntry.getBoolean("enaccheck"));//往来核算

                        assgrpEntrys.add(asstrp);

                        parentItemList.add(parentEntry.getDynamicObject("asstactitem").getString("number"));
                    }
                }

                String mitkz = item.getString("MITKZ");
                String katyp = item.getString("KATYP");

                if(StringUtils.isNotEmpty(mitkz) && ("D".equals(mitkz) || "K".equals(mitkz))){//核算维度默认为供应商
                    if(!parentItemList.contains("JY003")) {
                        QFilter assgFilter = new QFilter("number", QCP.equals, "JY003");
                        DynamicObject asstType = BusinessDataServiceHelper.loadSingle("bd_asstacttype", assgFilter.toArray());

                        DynamicObjectType assgrpType = assgrpEntrys.getDynamicObjectType();
                        DynamicObject asstrp = new DynamicObject(assgrpType);
                        asstrp.set("asstactitem", asstType);//核算维度
                        asstrp.set("isrequire", true);//必录
                        asstrp.set("isdetail", true);//明细
                        asstrp.set("enaccheck", false);//往来核算

                        assgrpEntrys.add(asstrp);
                    }
                } else if(StringUtils.isNotEmpty(katyp) && "1".equals(katyp)){//核算维度
                    //成本中心
                    QFilter assgFilter = new QFilter("number", QCP.equals, "JY001");
                    DynamicObject asstType = BusinessDataServiceHelper.loadSingle("bd_asstacttype", assgFilter.toArray());
                    DynamicObjectType assgrpType = assgrpEntrys.getDynamicObjectType();

                    if(!parentItemList.contains("JY001")) {
                        DynamicObject asstrp = new DynamicObject(assgrpType);
                        asstrp.set("asstactitem", asstType);//核算维度
                        asstrp.set("isrequire", true);//必录
                        asstrp.set("isdetail", true);//明细
                        asstrp.set("enaccheck", false);//往来核算

                        assgrpEntrys.add(asstrp);
                    }

                    //一级科目是5002和5301的，核算维度是成本中心 + 项目
                    if("5002".equals(parentNumber) || "5301".equals(parentNumber)){
                        if(!parentItemList.contains("JY002")) {
                            //项目
                            assgFilter = new QFilter("number", QCP.equals, "JY002");
                            asstType = BusinessDataServiceHelper.loadSingle("bd_asstacttype", assgFilter.toArray());

                            DynamicObject asstrp2 = new DynamicObject(assgrpType);
                            asstrp2.set("asstactitem", asstType);//核算维度
                            asstrp2.set("isrequire", false);//必录
                            asstrp2.set("isdetail", true);//明细
                            asstrp2.set("enaccheck", false);//往来核算

                            assgrpEntrys.add(asstrp2);
                        }
                    }
                }
                //币别核算
                accountInfo.set("acctcurrency", parent.getString("acctcurrency"));
            } else {
                if(!dataIds.contains(accountInfo.getLong("parent.id"))) {
                    dataIds.add(accountInfo.getLong("parent.id"));
                }
                dataIds.add(accountInfo.getLong("id"));

                continue;
            }

            accountInfo.set("name", name);//科目名称
            accountInfo.set("status", "C");//单据状态
            accountInfo.set("enable", "1");//使用状态

            logger.info("同步SAP主数据_会计科目，id：" + accountInfo.getLong("id") + "  -->  " + Long.valueOf(accountInfo.getString("id")));

            accountInfo.set("masterid", Long.valueOf(accountInfo.getString("id")));
            accountList.add(accountInfo);

            if(!dataIds.contains(accountInfo.getLong("parent.id"))) {
                dataIds.add(accountInfo.getLong("parent.id"));
            }
            dataIds.add(accountInfo.getLong("id"));
        }

        if (accountList.size() > 0) {
            DynamicObject[] saveDynamicObject = accountList.toArray(new DynamicObject[accountList.size()]);
//            Object[] save = SaveServiceHelper.save(saveDynamicObject);

            OperationResult resultSave = SaveServiceHelper.saveOperate(entityAccount, saveDynamicObject, OperateOption.create());

//            int length = save.length;
//            logger.info("同步[会计科目]完成，本次新增数量：{}," + err, length);

            result.put("code", "200");
            result.put("msg", "同步SAP主数据_会计科目，执行成功，本次同步数量" + saveDynamicObject.length + err);
        } else {
            result.put("code", "304");
            result.put("msg", "同步SAP主数据_会计科目_没有数据");
        }

        if(dataIds.size() > 0) {
            //批量分配
            List<Long> orgIds = new ArrayList();
            orgIds.add(companyDyn.getLong("id"));

            Map<Long, Map<Long, String>> resultValue = BaseDataServiceHelper.batchAssignWithDetail(entityAccount, DEFAULT_ORG_ID, dataIds, orgIds);
            if (!resultValue.isEmpty()) {
                result.put("code", "200");
                result.put("msg", "同步SAP主数据_会计科目，保存成功，但分配失败");
            }

        }

        logger.info("会计科目同步结果：" + result.toString());

        return result;
    }
}
