package com.malk.jianhui.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.kingdee.bos.webapi.entity.IdentifyInfo;
import com.kingdee.bos.webapi.entity.RepoRet;
import com.malk.jianhui.config.KDWebApiConf;
import com.malk.jianhui.entity.*;
import com.malk.jianhui.service.JianhuiService;
import com.malk.server.aliwork.YDConf;
import com.malk.server.aliwork.YDParam;
import com.malk.server.aliwork.YDSearch;
import com.malk.server.common.McR;
import com.malk.server.dingtalk.DDConf;
import com.malk.server.dingtalk.DDR_New;
import com.malk.service.aliwork.YDClient;
import com.malk.service.dingtalk.DDClient;
import com.malk.utils.UtilHttp;
import com.malk.utils.UtilMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.kingdee.bos.webapi.sdk.K3CloudApi;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

import static org.junit.Assert.fail;

@Slf4j
@Service
public class JianhuiServiceImpl implements JianhuiService {
    @Autowired
    private KDWebApiConf kdWebApiConf;

    @Autowired
    private YDClient ydClient;

    @Autowired
    private DDClient ddClient;

    @Autowired
    private DDConf ddConf;

    //单据状态
    private static final Map<String,String> FDOCUMENTSTATUS = new HashMap<>();
    static{
        FDOCUMENTSTATUS.put("Z","暂存");
        FDOCUMENTSTATUS.put("A","创建");
        FDOCUMENTSTATUS.put("B","审核中");
        FDOCUMENTSTATUS.put("C","已审核");
        FDOCUMENTSTATUS.put("D","重新审核");
    }

    //整单状态
    private static final Map<String,String> AUDITSTATUS = new HashMap<>();
    static{
        AUDITSTATUS.put("U","未审核");
        AUDITSTATUS.put("A","已审核");
        AUDITSTATUS.put("I","审核中");
        AUDITSTATUS.put("P","部分审核");
        AUDITSTATUS.put("R","重新审核");
    }

    //禁用状态
    private static final Map<String,String> FFORBIDSTATUS = new HashMap<>();
    static{
        FFORBIDSTATUS.put("A","否");
        FFORBIDSTATUS.put("B","是");
    }

    private static final Map<String,String> FFORBIDDENSTATUS = new HashMap<>();
    static{
        FFORBIDDENSTATUS.put("0","否");
        FFORBIDDENSTATUS.put("1","是");
    }

    private static final Map<String,String> FERPCLSID = new HashMap<>();
    static {
        FERPCLSID.put("10","资产");
        FERPCLSID.put("9","配置");
        FERPCLSID.put("2","自制");
        FERPCLSID.put("11","费用");
        FERPCLSID.put("12","模型");
        FERPCLSID.put("5","虚拟");
        FERPCLSID.put("7","一次性");
        FERPCLSID.put("13","产品系列");
        FERPCLSID.put("3","委外");
        FERPCLSID.put("4","特征");
        FERPCLSID.put("6","服务");
        FERPCLSID.put("1","外购");
    }

    private static final Map<String,String> BUSINESS_TYPE = new HashMap<>();
    static {
        BUSINESS_TYPE.put("8","发货检验");
        BUSINESS_TYPE.put("25","生产退料检验");
        BUSINESS_TYPE.put("26","委外退料检验");
        BUSINESS_TYPE.put("3","产品检验");
        BUSINESS_TYPE.put("20","其他检验");
        BUSINESS_TYPE.put("6","委外工序");
        BUSINESS_TYPE.put("10","受托材料检验");
        BUSINESS_TYPE.put("2","委外检验");
        BUSINESS_TYPE.put("21","工序巡检");
        BUSINESS_TYPE.put("7","退货检验");
        BUSINESS_TYPE.put("9","生产线检验");
        BUSINESS_TYPE.put("1","采购检验");
        BUSINESS_TYPE.put("4","库存检验");
        BUSINESS_TYPE.put("5","工序自制");
    }

    private static final Map<String,String> INSPECT_RESULT = new HashMap<>();
    static {
        INSPECT_RESULT.put("1","合格");
        INSPECT_RESULT.put("2","不合格");
        INSPECT_RESULT.put("3","保留");
    }

    private IdentifyInfo initIden(){
        //注意 1：此处不再使用参数形式传入用户名及密码等敏感信息，改为在登录配置文件中设置。
        //注意 2：必须先配置第三方系统登录授权信息后，再进行业务操作，详情参考各语言版本SDK介绍中的登录配置文件说明。
        //读取配置，初始化SDK
        IdentifyInfo iden = new IdentifyInfo();
        iden.setUserName(kdWebApiConf.getXKDApiUserName());
        iden.setAppId(kdWebApiConf.getXKDApiAppID());
        iden.setdCID(kdWebApiConf.getXKDApiAcctID());
        iden.setAppSecret(kdWebApiConf.getXKDApiAppSec());
        iden.setServerUrl(kdWebApiConf.getXKDApiServerUrl());

        return iden;
    }

    @Override
    //保存销售订单
    public McR saveSaleOrder(Map map) {
        String formInstId = getString(map.get("formInstId"));
        Map formData = ydClient.queryData(YDParam.builder()
                .formInstId(formInstId)
                .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();

        List<Map> details = (List<Map>) formData.get("tableField_m65t6bm5");

        //将时间戳转化为字符串 年月日时分秒格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");




        //请求参数，要求为json字符串
        Save save = new Save();
        Model model = new Model();

        //基本信息
        BillTypeID FBillTypeID = new BillTypeID(getString(formData.get("textField_m6t5hgw2")));//单据类型

        FNumber FSaleOrgId = new FNumber(getString(formData.get("textField_m6sqw8k1")));//销售组织

        FNumber FCustId = new FNumber(getString(formData.get("textField_m6ahh22d")));//客户

//        FNumber FReceiveId = new FNumber(getString(formData.get("textField_m6ahh22d")));//收货方

//        FNumber FSaleDeptId = new FNumber(getString(formData.get("textField_m6ahct6n")));//销售部门

        FNumber FSalerId = new FNumber(getString(formData.get("textField_m6t5xxrm")));//销售员

//        FNumber FSettleId = new FNumber(getString(formData.get("textField_m6ahh22d")));//结算方

//        FNumber FChargeId = new FNumber(getString(formData.get("textField_m6ahh22d")));//付款方

        //财务信息
        SaleOrderFinance saleOrderFinance = new SaleOrderFinance();

        saleOrderFinance.setFSettleCurrId(new FNumber(getString(formData.get("textField_m6ahh22i"))));//结算币别
//        saleOrderFinance.setFExchangeTypeId(new FNumber(getString(formData.get("textField_m6t6ay5x"))));//汇率类型
        saleOrderFinance.setFIsIncludedTax(getString(formData.get("radioField_m6a8ekan")).equals("是"));//是否含税
        saleOrderFinance.setFIsPriceExcludeTax(getString(formData.get("radioField_m6ahh22s")).equals("是"));//价外税

        /*saleOrderFinance.setFMarginLevel(0);//保证金比例（%）
        saleOrderFinance.setFMargin(0);//保证金
        saleOrderFinance.setFOverOrgTransDirect(false);//寄售生成跨组织调拨
        saleOrderFinance.setFAllDisCount(0);//整单折扣额
        saleOrderFinance.setFXPKID_F(0);//变更单主键*/

        //明细信息
        List<SaleOrderEntry> FSaleOrderEntry = new ArrayList<>();
        for (Map detail : details) {
            SaleOrderEntry saleOrderEntry = new SaleOrderEntry();
//            FNumber FStockOrgId = new FNumber(getString(detail.get("textField_m6sqw8js")));//库存组织
//            FNumber FSettleOrgIds = new FNumber(getString(detail.get("textField_m6sqw8jw")));//结算组织
//            FNumber FOwnerId = new FNumber(getString(detail.get("textField_m65t6bm9")));//货主

            saleOrderEntry.setFMaterialId(new FNumber(getString(detail.get("textField_m6sqw8jq"))));//物料编码
            saleOrderEntry.setFUnitID(new FNumber(getString(detail.get("textField_m6sqw8jz"))));//销售单位
            saleOrderEntry.setFPriceUnitId(new FNumber(getString(detail.get("textField_m6sqw8jz"))));//计量单位

//            saleOrderEntry.setFStockFNumber(FStockOrgId);
//            saleOrderEntry.setFSettleOrgIds(FSettleOrgIds);
//            saleOrderEntry.setFOwnerId(FOwnerId);
            saleOrderEntry.setFQty(new BigDecimal(getString(detail.get("numberField_m65t6bmb"))).doubleValue());//销售数量
//            saleOrderEntry.setFPriceUnitQty((int)detail.get("numberField_m65t6bmb"));//计价数量



            saleOrderEntry.setFIsFree(getString(detail.get("radioField_m6t6roed")).equals("是"));//是否赠品

            if (!getString(detail.get("radioField_m6t6roed")).equals("是")){
//                saleOrderEntry.setFPrice(new BigDecimal(getString(detail.get("numberField_m65t6bmd"))).doubleValue());//单价
                saleOrderEntry.setFTaxPrice(new BigDecimal(getString(detail.get("numberField_m65t6bme"))).doubleValue());//含税单价

                if (Objects.nonNull(detail.get("numberField_m65t6bmf"))){
                    saleOrderEntry.setFEntryTaxRate(new BigDecimal(getString(detail.get("numberField_m65t6bmf"))).doubleValue());//税率（%）
//                    saleOrderEntry.setFTaxAmount_LC(new BigDecimal(getString(detail.get("numberField_m65t6bmg"))).doubleValue());//税额（本位币）
                }
/*                if (Objects.nonNull(detail.get("numberField_m65t6bmh"))){
                    saleOrderEntry.setFAmount_LC(new BigDecimal(getString(detail.get("numberField_m65t6bmh"))).doubleValue());//金额（本位币）
                }

                saleOrderEntry.setFAllAmount_LC(new BigDecimal(getString(detail.get("numberField_m65t6bmi"))).doubleValue());//价税合计（本位币）*/

            }

            saleOrderEntry.setFDeliveryDate(sdf.format(new Date((long) detail.get("dateField_m65t6bmj"))));//要货日期
//            saleOrderEntry.setFOwnerTypeId("BD_OwnerOrg");//货主类型
            saleOrderEntry.setFEntryNote(getString(detail.get("textareaField_m6t6roeg")));//备注
//            saleOrderEntry.setF_WMVJ_Decimal(39913500);//方数
//            saleOrderEntry.setF_WMVJ_Amount(111);//金额(配件）
//            saleOrderEntry.setF_WMVJ_Qty(12);//即时库存
//            saleOrderEntry.setF_WMVJ_CheckBox(getString(detail.get("radioField_m6t6roef")).equals("是"));//是否生产

            FSaleOrderEntry.add(saleOrderEntry);
        }


//        model.setFID(0);//实体主键
        model.setFBillTypeID(FBillTypeID);//单据类型
        model.setFDate(sdf.format(new Date((long) formData.get("dateField_m65t6bkv"))));//日期
        model.setFSaleOrgId(FSaleOrgId);//销售组织
        model.setFCustId(FCustId);//客户
//        model.setFReceiveId(FReceiveId);//收货方
//        model.setFSaleDeptId(FSaleDeptId);//销售部门
        model.setFSalerId(FSalerId);//销售员
        model.setFNote(getString(formData.get("textareaField_m6sqw8jo")));//备注
//        model.setFSettleId(FSettleId);//结算方
//        model.setFChargeId(FChargeId);//付款方

//        model.setFNetOrderBillId(0);//移动销售订单ID
//        model.setFOppID(0);//商机内码
//        model.setFISINIT(false);//是否期初单据
//        model.setFIsMobile(false);//来自移动（弃用）
//        model.setFContractId(0);//销售合同内码
//        model.setFIsUseOEMBomPush(false);//生成受托加工材料清单
//        model.setFXPKID_H(0);//变更单主键
//        model.setFIsUseDrpSalePOPush(false);//生成分销采购订单
//        model.setFIsCreateStraightOutIN(false);//生成直运出入库
        model.setFSaleOrderFinance(saleOrderFinance);//财务信息
        model.setFSaleOrderEntry(FSaleOrderEntry);//订单明细

        save.setModel(model);
        Gson gson2 = new Gson();
        String jsonData = gson2.toJson(save);

//        String jsonData = JSONObject.toJSONString(save);
//        String jsonData = "{\"Model\":{\"FBillTypeID\":{\"FNUMBER\":\"XSDD01_SYS\"},\"FDate\":\"2025-02-27\",\"FSaleOrgId\":{\"FNumber\":\"100\"},\"FCustId\":{\"FNumber\":\"C0615\"},\"FSalerId\":{\"FNumber\":\"0118_0012_1\"},\"FNote\":\"\",\"FSaleOrderFinance\":{\"FSettleCurrId\":{\"FNumber\":\"PRE001\"},\"FIsIncludedTax\":\"false\"},\"FSaleOrderEntry\":[{\"FMaterialId\":{\"FNumber\":\"C2070502\"},\"FUnitID\":{\"FNumber\":\"Pcs\"},\"FQty\":1,\"FPriceUnitId\":{\"FNumber\":\"Pcs\"},\"FTaxPrice\":115,\"FIsFree\":false,\"FEntryNote\":\"\",\"FEntryTaxRate\":0,\"FDeliveryDate\":\"2025-02-28\",\"FSettleOrgIds\":{\"FNumber\":\"100\"}}]}}";


        log.info(jsonData);

       try{
            K3CloudApi client = new K3CloudApi(initIden());
            //业务对象标识
            String formId = "SAL_SaleOrder";
            //调用接口
            String resultJson = client.save(formId,jsonData);
            //用于记录结果
            Gson gson = new Gson();
            //对返回结果进行解析和校验
            RepoRet repoRet = gson.fromJson(resultJson, RepoRet.class);



            if (isTrue(repoRet)){
                String id = repoRet.getResult().getId();

                Submit submit = new Submit();
                submit.setIds(id);
                //提交销售订单
                String resultJson2 = client.submit(formId, JSONObject.toJSONString(submit));
                RepoRet repoRet2 = gson.fromJson(resultJson2, RepoRet.class);
                isTrue(repoRet2);

                String orderCode = repoRet2.getResult().getResponseStatus().getSuccessEntitys().get(0).getNumber();

                ydClient.operateData(YDParam.builder()
                        .formInstId(formInstId)
                        .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("textField_m6a8ekal",orderCode)))
                        .build(), YDConf.FORM_OPERATION.update);

                if (isTrue(repoRet2)){
                    Audit audit = new Audit();
                    audit.setNumbers(Arrays.asList(orderCode));
                    //审核销售订单
                    String resultJson3 = client.audit(formId,JSONObject.toJSONString(audit));
                    RepoRet repoRet3 = gson.fromJson(resultJson3, RepoRet.class);
                    isTrue(repoRet3);
                }
            }
        } catch (Exception e) {
            fail(e.getMessage());
        }

        return McR.success();
    }

    private String getString(Object object){
        return object == null ? "" : object.toString();
    }


    @Override
    public McR syncCustomers() {
        try {
            K3CloudApi client = new K3CloudApi(initIden());

            List<Map> result = new ArrayList<>();
            List<Map> customerList = new ArrayList<>();

            int startRow = 0;
            int limit = 2000;

            BillQuery billQuery = new BillQuery();
            billQuery.setFormId("BD_Customer");
            billQuery.setFieldKeys("FNumber,FName,FShortName,FDocumentStatus,FForbidStatus,FUseOrgId,FAPPROVERID,FAPPROVEDATE,FGroup");
            List<Map> filterString = new ArrayList<>();
            //修改时间为昨天到今天
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FModifyDate","265","1","","","0"));
//            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FModifyDate","39","2025-03-06 00:00:00","","","0"));
            billQuery.setFilterString(filterString);
            billQuery.setLimit(limit);
            do {
                billQuery.setStartRow(startRow);
                String s = client.billQuery(JSONObject.toJSONString(billQuery));
                result = (List<Map>)JSONObject.parse(s);
                customerList.addAll(result);

                startRow += limit;
            }while (result.size() == limit);

            for (Map customer : customerList) {
                Map formData = new HashMap();
                formData.put("textField_m67c6m6f",customer.get("FNumber"));//客户编码
                formData.put("textField_m67c6m6e",customer.get("FName"));//客户名称
                formData.put("textField_m67c6m6g",customer.get("FShortName"));//简称
                formData.put("textField_m67c6m6h",FDOCUMENTSTATUS.get(customer.get("FDocumentStatus").toString()));//单据状态
                formData.put("textField_m67c6m6i",FFORBIDSTATUS.get(customer.get("FForbidStatus").toString()));//禁用状态
                formData.put("textField_m67c6m6j",customer.get("FUseOrgId"));//使用组织
                formData.put("textField_m67c6m6k",customer.get("FAPPROVERID"));//审核人
                formData.put("textField_m67c6m6l",customer.get("FAPPROVEDATE"));//审核日期
                formData.put("textField_m67c6m6m",customer.get("FGroup"));//客户分组


                ydClient.operateData(YDParam.builder()
                        .formUuid("FORM-C3E9A165EEAB4232BD2F04F536E195D1WINH")
                        .searchFieldJson(JSONObject.toJSONString(Arrays.asList(new YDSearch("textField_m67c6m6f",customer.get("FNumber"),"客户编码", YDSearch.Type.TEXT_FIELD,YDSearch.Operator.EQ))))
                        .formDataJson(JSONObject.toJSONString(formData))
                        .build(), YDConf.FORM_OPERATION.upsert);

            }
        }catch (Exception e){
            fail(e.getMessage());
        }
        return McR.success();
    }

    @Override
    public McR syncSalesman() {
        try {
            K3CloudApi client = new K3CloudApi(initIden());

            int startRow = 0;
            int limit = 2000;

            BillQuery billQuery = new BillQuery();

            billQuery.setLimit(limit);
            billQuery.setFormId("BD_OPERATOR");
            billQuery.setFieldKeys("FNumber,FName,FForbiddenStatus,FBizOrgId");
            List<Map> filterString = new ArrayList<>();
            //修改时间为昨天到今天
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FModifyDate","265","1","","","0"));
//            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FModifyDate","39","2025-03-06 00:00:00","","","0"));
            billQuery.setFilterString(filterString);

            List<Map> result = new ArrayList<>();
            List<Map> operatorList = new ArrayList<>();


            do {
                billQuery.setStartRow(startRow);
                String s = client.billQuery(JSONObject.toJSONString(billQuery));
                result = (List<Map>)JSONObject.parse(s);
                operatorList.addAll(result);

                startRow += limit;
            }while (result.size() == limit);

            for (Map operator : operatorList) {
                Map formData = new HashMap();
                formData.put("textField_m67pb4tl",operator.get("FName"));//业务员名称
                formData.put("textField_m67pb4tn",operator.get("FNumber"));//业务员编码
                formData.put("textField_m67pb4tm",operator.get("FBizOrgId"));//业务组织
                formData.put("textField_m67pb4tk",FFORBIDDENSTATUS.get(operator.get("FForbiddenStatus").toString()));//禁用状态

                String FNumber = operator.get("FNumber").toString();
                //查找员工任岗信息
                View view = new View();
                view.setNumber(FNumber);
                String resultJson = client.view("BD_NEWSTAFF", JSONObject.toJSONString(view));
                Gson gson = new Gson();
                RepoRet repoRet = gson.fromJson(resultJson, RepoRet.class);
                if (isTrue(repoRet)){
                    Map positionInfo = (Map) repoRet.getResult().getResult();
                    Map position = (Map) positionInfo.get("Position");
                    String positionValue = ((List<Map>) position.get("Name")).get(0).get("Value").toString();

                    Map dept = (Map) position.get("FDept");
                    String deptValue = ((List<Map>) dept.get("Name")).get(0).get("Value").toString();

                    formData.put("textField_m67pb4td",positionValue);//岗位
                    formData.put("textField_m67pb4tb",deptValue);//部门
                }

                ydClient.operateData(YDParam.builder()
                        .formUuid("FORM-250CD995257D4CB08F99786E47D8D51BCUDP")
                        .searchFieldJson(JSONObject.toJSONString(Arrays.asList(new YDSearch("textField_m67pb4tn",operator.get("FNumber"),"业务员编码", YDSearch.Type.TEXT_FIELD,YDSearch.Operator.EQ))))
                        .formDataJson(JSONObject.toJSONString(formData))
                        .build(), YDConf.FORM_OPERATION.upsert);
            }
        }catch (Exception e){
            fail(e.getMessage());
        }

        return McR.success();
    }

    @Override
    public McR syncMaterial() {
        try {
            K3CloudApi client = new K3CloudApi(initIden());

            List<Map> result = new ArrayList<>();
            List<Map> materialList = new ArrayList<>();

            int startRow = 0;
            int limit = 2000;

            BillQuery billQuery = new BillQuery();
            billQuery.setFormId("BD_MATERIAL");
            billQuery.setFieldKeys("FUseOrgId,FNumber,FName,FSpecification,FDocumentStatus,FForbidStatus,FErpClsID,FBaseUnitId,FRefStatus");
            List<Map> filterString = new ArrayList<>();
            //修改时间或审核日期为昨天到今天
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FModifyDate","265","1","","","1"));
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FApproveDate","265","1","","","0"));

//            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FModifyDate","39","2025-03-12 00:00:00","","","0"));//修改日期大于等于xx
//            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FModifyDate","16","2025-03-14 00:00:00","","","0"));//修改日期小于等于xx
//            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FCreateDate","39","2025-08-24 00:00:00","","","0"));//创建日期大于等于xx
//            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FCreateDate","16","2025-08-25 00:00:00","","","0"));//创建日期小于等于xx
//            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FApproveDate","39","2025-03-14 00:00:00","","","0"));//审核日期大于等于xx
//            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FNumber","67","Y0070002","","","0"));//编码等于xx
//            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FNumber","17","0001","","","0"));//编码包含xx


            billQuery.setFilterString(filterString);
            billQuery.setLimit(limit);
            do {
                billQuery.setStartRow(startRow);
                String s = client.billQuery(JSONObject.toJSONString(billQuery));
                result = (List<Map>)JSONObject.parse(s);
                materialList.addAll(result);

                startRow += limit;
            }while (result.size() == limit);

            for (Map material : materialList) {
                Map formData = new HashMap();
                formData.put("textField_m6ak640p",material.get("FUseOrgId"));//使用组织
                formData.put("textField_m6ak640v",material.get("FNumber"));//编码
                formData.put("selectField_m83u6et1",getString(material.get("FNumber")).substring(0,1).equals("C") ? "成品" : "配件");
                formData.put("textField_m6ak640w",material.get("FName"));//名称
                formData.put("textField_m6ak640x",material.get("FSpecification"));//规格型号
                formData.put("textField_m6ak6413",FDOCUMENTSTATUS.get(material.get("FDocumentStatus").toString()));//单据状态
                formData.put("textField_m6ak6414",FFORBIDSTATUS.get(material.get("FForbidStatus").toString()));//禁用状态
                formData.put("textField_m6ak6415",FERPCLSID.get(material.get("FErpClsID").toString()));//物料属性
                formData.put("textField_m6ak641c",material.get("FRefStatus"));//已使用

                //查找计量单位信息
                String FBaseUnitId = material.get("FBaseUnitId").toString();
                View view = new View();
                view.setId(FBaseUnitId);
                String resultJson = client.view("BD_UNIT", JSONObject.toJSONString(view));
                Gson gson = new Gson();
                RepoRet repoRet = gson.fromJson(resultJson, RepoRet.class);
                if (isTrue(repoRet)){
                    Map unitInfo = (Map) repoRet.getResult().getResult();
                    String unitName = ((List<Map>) unitInfo.get("Name")).get(0).get("Value").toString();

                    String unitCode = unitInfo.get("Number").toString();

                    formData.put("textField_m6ak6416",unitName);//基本单位
                    formData.put("textField_m6ak641d",unitCode);//单位编码
                }


                ydClient.operateData(YDParam.builder()
                        .formUuid("FORM-2A5CAB7EB91D493AAFC90D8C7479A7F5KPR7")
                        .searchFieldJson(JSONObject.toJSONString(Arrays.asList(new YDSearch("textField_m6ak640v",material.get("FNumber"),"编码", YDSearch.Type.TEXT_FIELD,YDSearch.Operator.EQ))))
                        .formDataJson(JSONObject.toJSONString(formData))
                        .build(), YDConf.FORM_OPERATION.upsert);

            }
        }catch (Exception e){
            fail(e.getMessage());
        }
        return McR.success();
    }

    @Override
    public McR saveForecastOrder(Map map) {
        String formInstId = getString(map.get("formInstId"));

        Map formData = ydClient.queryData(YDParam.builder()
                .formInstId(formInstId)
                .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();

        //将时间戳转化为字符串 年月日时分秒格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        Save save = new Save();
        Model model = new Model();
        model.setFForeOrgId(new FNumber(getString(formData.get("textField_m6yh6qcs"))));//预测组织
        model.setFBillTypeID(new BillTypeID(getString(formData.get("textField_m6yh6qcr"))));//单据类型
        model.setFDate(sdf.format(new Date((long)formData.get("dateField_m65vi32c"))));//单据日期
        model.setFDescription(getString(formData.get("textareaField_m6yh6qck")));//备注
        model.setF_WMVJ_Date_qtr(sdf.format(new Date((long)formData.get("dateField_m7lqobzp"))));//要货日期

        List<Map> details = (List<Map>) formData.get("tableField_m65vi32k");
        List<Object> FEntity = new ArrayList<>();

        for (Map detail : details) {
            ForecastEntity forecastEntity = new ForecastEntity();

            forecastEntity.setFCustID(new FNumber(getString(detail.get("textField_m6yh6qcu"))));//客户
            //        forecastEntity.setFProductType("0");
            forecastEntity.setFMaterialID(new FNumber(getString(detail.get("textField_m65vi32o"))));//物料
            forecastEntity.setFUnitID(new FNumber(getString(detail.get("textField_m6yh6qcx"))));//单位
            forecastEntity.setFQty(new BigDecimal(getString(detail.get("numberField_m65vi32s"))).doubleValue());//数量
            forecastEntity.setFStartDate(sdf.format(new Date((long) detail.get("dateField_m65vi32t"))));//预测开始日期
            forecastEntity.setFEndDate(sdf.format(new Date((long) detail.get("dateField_m65vi32u"))));//预测结束日期

            //均化类型  W:周，M:月，D:日，N:不均化
            String FAVERATYPE = getString(detail.get("selectField_m65vi32v"));
            switch (FAVERATYPE){
                case "不均化" : forecastEntity.setFAVERATYPE("N");break;
                case "日" : forecastEntity.setFAVERATYPE("D");break;
                case "周" : forecastEntity.setFAVERATYPE("W");break;
                case "月" : forecastEntity.setFAVERATYPE("M");break;
                default : break;
            }

            //均化周期
            if (Objects.nonNull(detail.get("numberField_m65vi32w"))){
                forecastEntity.setFAveraCycle((int) detail.get("numberField_m65vi32w"));
            }

            //预留类型 1:弱预留，3:强预留
            String FReserveType = getString(detail.get("selectField_m65vi32z"));
            switch (FReserveType){
                case "强预留" : forecastEntity.setFReserveType("3");
                case "弱预留" : forecastEntity.setFReserveType("1");
            }

            //需求优先级
            if (Objects.nonNull(detail.get("numberField_m6yh6qcy"))){
                forecastEntity.setFPriority((int) detail.get("numberField_m6yh6qcy"));
            }

            forecastEntity.setFRemark(getString(detail.get("textField_m65vi330")));//备注
//        forecastEntity.setFChangeFlag("0");//变更标志
            FEntity.add(forecastEntity);

        }

        model.setFEntity(FEntity);
        save.setModel(model);

        try{
            K3CloudApi client = new K3CloudApi(initIden());
            //业务对象标识
            String formId = "PLN_FORECAST";
            //调用接口
            String resultJson = client.save(formId,JSONObject.toJSONString(save));
            //用于记录结果
            Gson gson = new Gson();
            //对返回结果进行解析和校验
            RepoRet repoRet = gson.fromJson(resultJson, RepoRet.class);

            if (isTrue(repoRet)){
                String id = repoRet.getResult().getId();

                Submit submit = new Submit();
                submit.setIds(id);
                //提交
                String resultJson2 = client.submit(formId, JSONObject.toJSONString(submit));
                RepoRet repoRet2 = gson.fromJson(resultJson2, RepoRet.class);
                isTrue(repoRet2);

                String orderCode = repoRet2.getResult().getResponseStatus().getSuccessEntitys().get(0).getNumber();

                ydClient.operateData(YDParam.builder()
                        .formInstId(formInstId)
                        .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("textField_m6ydmllb",orderCode)))
                        .build(), YDConf.FORM_OPERATION.update);

                if (isTrue(repoRet2)){
                    Audit audit = new Audit();
                    audit.setIds(id);
                    //审核
                    String resultJson3 = client.audit(formId,JSONObject.toJSONString(audit));
                    RepoRet repoRet3 = gson.fromJson(resultJson3, RepoRet.class);
                    isTrue(repoRet3);
                }
            }
        } catch (Exception e) {
            fail(e.getMessage());
        }



        return McR.success();
    }

    @Override
    public McR saveDefectiveOrder(Map map) {
        String formInstId = getString(map.get("formInstId"));

        Map formData = ydClient.queryData(YDParam.builder()
                .formInstId(formInstId)
                .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();

        //将时间戳转化为字符串 年月日时分秒格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


        Save save = new Save();

        Model model = new Model();
        model.setFBillTypeID(new BillTypeID(getString(formData.get("textField_m6yntxn9"))));//单据类型
        //业务类型 1：采购检验 2：委外检验 3：来料不良
        String FBusinessType = getString(formData.get("selectField_m64pw0gf"));
        switch (FBusinessType){
            case "采购检验": model.setFBusinessType("1");break;
            case "委外检验": model.setFBusinessType("2");break;
            case "来料不良": model.setFBusinessType("3");break;
            default:break;
        }

        model.setFDate(sdf.format(new Date((long) formData.get("dateField_m64pw0gk"))));//日期
        model.setFSourceOrgId(new FNumber(getString(formData.get("textField_m6yntxn7"))));//来源组织
        model.setFInspectOrgId(new FNumber(getString(formData.get("textField_m6yntxnl"))));//质检组织
        model.setFInspectDepId(new FNumber(getString(formData.get("textField_m6yntxnc"))));//质检部门
        model.setFDescription(getString(formData.get("textareaField_m6yntxnh")));//备注

        List<Object> FEntity = new ArrayList<>();
        List<Map> details = (List<Map>) formData.get("tableField_m64pw0gm");

        for (Map detail : details) {
            DefectEntity defectEntity = new DefectEntity();
            defectEntity.setFMateridlId(new FNumber(getString(detail.get("textField_m64pw0go"))));//物料
            defectEntity.setFSupplierId(new FNumber(getString(detail.get("textField_m6yumh8w"))));//供应商
            defectEntity.setFUnitID(new FNumber(getString(detail.get("textField_m6yntxnj"))));//单位

            //检验单使用决策
            String FUsePolicy = getString(detail.get("selectField_mf3yq2lz"));
            switch (FUsePolicy){
                case "作业不良": defectEntity.setFUsePolicy("N");break;
                case "返工": defectEntity.setFUsePolicy("J");break;
                case "报废": defectEntity.setFUsePolicy("D");break;
                case "接收": defectEntity.setFUsePolicy("A");break;
                case "返修": defectEntity.setFUsePolicy("C");break;
                case "工废": defectEntity.setFUsePolicy("I");break;
                case "判退": defectEntity.setFUsePolicy("F");break;
                case "不良": defectEntity.setFUsePolicy("G");break;
                case "让步接收": defectEntity.setFUsePolicy("B");break;
                case "挑选（全检）": defectEntity.setFUsePolicy("E");break;
                case "来料不良": defectEntity.setFUsePolicy("M");break;
                case "料废": defectEntity.setFUsePolicy("H");break;
                default:break;
            }

            defectEntity.setFInspectDefectQty((int) detail.get("numberField_m82qkv1u"));//检验不良数量

            //不良处理 A：接收 B：让步接收 F：判退
            String FDefProcess = getString(detail.get("selectField_m64pw0gt"));
            switch (FDefProcess){
                case "接收": defectEntity.setFDefProcess("A");break;
                case "让步接收": defectEntity.setFDefProcess("B");break;
                case "判退": defectEntity.setFDefProcess("F");break;
                default:break;
            }
            defectEntity.setFDefectiveQty((int) detail.get("numberField_m64pw0gu"));//不良数量


            //关联检验单
            List<Object> linkEntity = new ArrayList<>();
            Map link = new HashMap();
            HashMap<String, Object> detailLink = new HashMap<>();

//            link.put("FEntity_Link_FFlowId", "");//业务流程图
//            link.put("FEntity_Link_FFlowLineId", "");//推进路线
            link.put("FEntity_Link_FRuleId","QM_Inspect2DefProecess");//转换规则
//            link.put("FEntity_Link_FSTableId", "");//源单表内码
            link.put("FEntity_Link_FSTableName","T_QM_INSPECTBILLENTRY");//源单表
            link.put("FEntity_Link_FSBillId",formData.get("numberField_m86nq0a5"));//源单内码
            link.put("FEntity_Link_FSId", detail.get("numberField_m873a1q2"));//源单分录内码

            linkEntity.add(link);

            defectEntity.setFEntity_Link(linkEntity);


            FEntity.add(defectEntity);
        }

        model.setFEntity(FEntity);

        save.setModel(model);

        try{
            K3CloudApi client = new K3CloudApi(initIden());
            //业务对象标识
            String formId = "QM_DefectProcessBill";
            //调用接口
            String resultJson = client.save(formId,JSONObject.toJSONString(save));
            //用于记录结果
            Gson gson = new Gson();
            //对返回结果进行解析和校验
            RepoRet repoRet = gson.fromJson(resultJson, RepoRet.class);

            if (isTrue(repoRet)){
                String id = repoRet.getResult().getId();

                Submit submit = new Submit();
                submit.setIds(id);
                //提交
                String resultJson2 = client.submit(formId, JSONObject.toJSONString(submit));
                RepoRet repoRet2 = gson.fromJson(resultJson2, RepoRet.class);
                if (isTrue(repoRet2)){
                    String orderCode = repoRet2.getResult().getResponseStatus().getSuccessEntitys().get(0).getNumber();

                    ydClient.operateData(YDParam.builder()
                            .formInstId(formInstId)
                            .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("textField_m6yntxmz",orderCode)))
                            .build(), YDConf.FORM_OPERATION.update);

                    Audit audit = new Audit();
                    audit.setIds(id);

                    //审核
                    String resultJson3 = client.audit(formId,JSONObject.toJSONString(audit));
                    RepoRet repoRet3 = gson.fromJson(resultJson3, RepoRet.class);
                    if (isTrue(repoRet3)){
                        //更新检验单使用决策
                        String formId2 = "QM_InspectBill";

                        Save save2 = new Save();
                        Model model2 = new Model();
                        model2.setFID((int)formData.get("numberField_m86nq0a5"));//检验单id
                        List<Object> FEntityList = new ArrayList<>();
                        for (Map detail : details) {
                            Map FEntity2 = new HashMap();
                            FEntity2.put("FEntryID",detail.get("numberField_m873a1q2"));//分录明细id

                            List<Map> FPolicyDetailList = new ArrayList<>();
                            Map FPolicyDetail = new HashMap();
                            FPolicyDetail.put("FDetailID",detail.get("numberField_m8fkgsvo"));//使用决策id

                            //不良处理 A：接收 B：让步接收 F：判退
                            String FDefProcess = getString(detail.get("selectField_m64pw0gt"));
                            switch (FDefProcess){
                                case "接收": FPolicyDetail.put("FUsePolicy","A");break;
                                case "让步接收": FPolicyDetail.put("FUsePolicy","B");break;
                                case "判退": FPolicyDetail.put("FUsePolicy","F");break;
                                default:break;
                            }

                            FPolicyDetailList.add(FPolicyDetail);

                            FEntity2.put("FPolicyDetail",FPolicyDetailList);

                            FEntityList.add(FEntity2);
                        }
                        model2.setFEntity(FEntityList);

                        save2.setModel(model2);

                        String resultJson4 = client.save(formId2,JSONObject.toJSONString(save2));

                        RepoRet repoRet4 = gson.fromJson(resultJson4, RepoRet.class);
                        isTrue(repoRet4);
                    }
                }
            }
        } catch (Exception e) {
            McR.errorUnknown(e.getMessage());
        }

        return McR.success();
    }

    @Override
    public McR syncSupplier() {
        try {
            K3CloudApi client = new K3CloudApi(initIden());

            int startRow = 0;
            int limit = 2000;

            BillQuery billQuery = new BillQuery();

            billQuery.setLimit(limit);
            billQuery.setFormId("BD_Supplier");
            billQuery.setFieldKeys("FNumber,FUseOrgId,FName,FShortName,FGroup,FAuditorId,FAuditDate,FDocumentStatus,FForbidStatus");
            List<Map> filterString = new ArrayList<>();
            //修改时间为昨天到今天
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FModifyDate","265","1","","","0"));
//            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FModifyDate","39","2025-03-06 00:00:00","","","0"));
            billQuery.setFilterString(filterString);

            List<Map> result = new ArrayList<>();
            List<Map> operatorList = new ArrayList<>();


            do {
                billQuery.setStartRow(startRow);
                String s = client.billQuery(JSONObject.toJSONString(billQuery));
                result = (List<Map>)JSONObject.parse(s);
                operatorList.addAll(result);

                startRow += limit;
            }while (result.size() == limit);

            for (Map operator : operatorList) {
                Map formData = new HashMap();
                formData.put("textField_m6yuw4j2",operator.get("FName"));//名称
                formData.put("textField_m6yuw4j3",operator.get("FShortName"));//简称
                formData.put("textField_m6yuw4iw",operator.get("FNumber"));//编码
                formData.put("textField_m6yuw4j4",operator.get("FUseOrgId"));//组织
                if ((int) operator.get("FGroup") == 204305){
                    formData.put("textField_m6yuw4ja","宁波健辉供应商");//供应商分组
                }

                formData.put("textField_m6yuw4jb",operator.get("FAuditorId"));//审核人
                formData.put("textField_m6yuw4jc",operator.get("FAuditDate"));//审核日期
                formData.put("textField_m6yuw4jd",FDOCUMENTSTATUS.get(getString(operator.get("FDocumentStatus"))));//数据状态
                formData.put("textField_m67pb4tk",FFORBIDSTATUS.get(getString(operator.get("FForbiddenStatus"))));//禁用状态

                ydClient.operateData(YDParam.builder()
                        .formUuid("FORM-1DAEA1675CAE47F49BE1F86A034D695191W1")
                        .searchFieldJson(JSONObject.toJSONString(Arrays.asList(new YDSearch("textField_m6yuw4iw",operator.get("FNumber"),"编码", YDSearch.Type.TEXT_FIELD,YDSearch.Operator.EQ))))
                        .formDataJson(JSONObject.toJSONString(formData))
                        .build(), YDConf.FORM_OPERATION.upsert);
            }
        }catch (Exception e){
            fail(e.getMessage());
        }

        return McR.success();
    }

    @Override
    public McR syncPurchaseOrder() {
        try {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");

            //业务对象标识
            String formId = "PUR_PurchaseOrder";

            K3CloudApi client = new K3CloudApi(initIden());
            Gson gson = new Gson();

            //查询当天审核中数据
            BillQuery billQuery = new BillQuery();
            billQuery.setFormId(formId);
            billQuery.setFieldKeys("FBillNo");
            billQuery.setStartRow(0);
            billQuery.setLimit(100);

            List<Map> filterString = new ArrayList<>();
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FDocumentStatus","105","B","","","0"));
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FCreateDate","13","","","","0"));
            billQuery.setFilterString(filterString);

            String resultJson = client.billQuery(JSONObject.toJSONString(billQuery));

            List<Map> list = (List<Map>) JSONObject.parse(resultJson);

            for (Map map : list) {
                String fBillNo = getString(map.get("FBillNo"));

                //查询宜搭中是否已添加该采购订单
                List<Map> data = (List<Map>) ydClient.queryData(YDParam.builder()
                        .formUuid("FORM-050FE2BED20644318C2521F9C7B8D9D1FIFO")
                        .searchFieldJson(JSONObject.toJSONString(UtilMap.map("textField_m703yqyb", fBillNo)))
                        .build(), YDConf.FORM_QUERY.retrieve_list).getData();

                //没有则新增
                if (data.isEmpty()){
                    View view = new View();
                    view.setNumber(fBillNo);
                    String resultJson2 = client.view(formId,JSONObject.toJSONString(view));

                    RepoRet repoRet = gson.fromJson(resultJson2, RepoRet.class);
                    if (isTrue(repoRet)){
                        Map result = (Map) repoRet.getResult().getResult();

                        Map formData = new HashMap();
                        formData.put("selectField_m65wv53k",getMultiLanguageTextName(result.get("BillTypeId")));//单据类型
                        formData.put("selectField_m65wv53w",getMultiLanguageTextName(result.get("SupplierId")));//供应商

                        //业务类型
                        String businessType = getString(result.get("BusinessType"));
                        switch (businessType){
                            case "CG":formData.put("selectField_m65wv53r","标准采购");break;
                            case "WW":formData.put("selectField_m65wv53r","标准委外");break;
                            case "ZCCG":formData.put("selectField_m65wv53r","资产采购");break;
                            case "ZYCG":formData.put("selectField_m65wv53r","直运采购");break;
                            case "FYCG":formData.put("selectField_m65wv53r","费用采购");break;
                            case "VMICG":formData.put("selectField_m65wv53r","VMI采购");break;
                            case "cscg":formData.put("selectField_m65wv53r","测试采购");break;
                            case "DRPCG":formData.put("selectField_m65wv53r","分销购销");break;
                            default:;break;
                        }

                        formData.put("selectField_m65wv542",getMultiLanguageTextName(result.get("PurchaseOrgId")));//采购组织
                        formData.put("selectField_m65wv543",getMultiLanguageTextName(result.get("PurchaseDeptId")));//采购部门
                        formData.put("textField_m703yqyb",getString(result.get("BillNo")));//单据编号

                        // 解析字符串为 LocalDateTime
                        LocalDateTime localDateTime = LocalDateTime.parse(getString(result.get("Date")), formatter);

                        // 将 LocalDateTime 转换为 ZonedDateTime
                        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());

                        formData.put("dateField_m65wv548",zonedDateTime.toInstant().toEpochMilli());//采购日期

                        //验收方式
                        String facctype = getString(result.get("FACCTYPE"));
                        switch (facctype){
                            case "A":formData.put("selectField_m703yqyc","金额验收");break;
                            case "Q":formData.put("selectField_m703yqyc","数量验收");break;
                            case "R":formData.put("selectField_m703yqyc","比例验收");break;
                            default:break;
                        }

                        Map SupplierId = (Map) result.get("SupplierId");
                        Map supplierBusiness = ((List<Map>) SupplierId.get("SupplierBusiness")).get(0);
                        if (Objects.nonNull(supplierBusiness)){
                            formData.put("selectField_m65wv54f",getMultiLanguageTextName(supplierBusiness.get("ProviderId")));//供货方
                            formData.put("textField_m65wv54g",getMultiLanguageTextName(supplierBusiness.get("ProviderContactId")));//供货方联系人
                        }

                        formData.put("textField_m65wv54m",getString(result.get("ProviderEMail")));//邮箱

                        Map supplierFinance = ((List<Map>) SupplierId.get("SupplierFinance")).get(0);
                        if (Objects.nonNull(supplierFinance)){
                            formData.put("selectField_m65wv54r",getMultiLanguageTextName(supplierFinance.get("SettleId")));//结算方
                            formData.put("selectField_m65wv54s",getMultiLanguageTextName(supplierFinance.get("ChargeId")));//收款方
                        }


                        List<Map> details = new ArrayList<>();

                        List<Map> poOrderEntry = (List<Map>) result.get("POOrderEntry");
                        for (Map po : poOrderEntry) {
                            Map detail = new HashMap();
//                            detail.put("textField_m703yqyj",getString(po.get("ProductType")));//委外产品类型
                            detail.put("textField_m703yqyk",getEntryNumber(po.get("MaterialId")));//物料编码
                            detail.put("textField_m65wv551",getMultiLanguageTextName(po.get("MaterialId")));//物料名称
                            detail.put("textField_m65wv552",getMultiLanguageTextSpecification(po.get("MaterialId")));//物料规格
                            detail.put("textField_m65wv553",getMultiLanguageTextName(po.get("UnitId")));//采购单位
                            detail.put("numberField_m65wv554",po.get("Qty"));//采购数量
                            detail.put("textField_m65wv556",getMultiLanguageTextName(po.get("PriceUnitId")));//计价单位
                            detail.put("textField_m65wv555",po.get("PriceUnitQty"));//计价数量

                            if (Objects.nonNull(po.get("DeliveryDate"))){
                                // 解析字符串为 LocalDateTime
                                localDateTime = LocalDateTime.parse(getString(po.get("DeliveryDate")).substring(0,19), formatter);

                                // 将 LocalDateTime 转换为 ZonedDateTime
                                zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());

                                detail.put("dateField_m65wv557",zonedDateTime.toInstant().toEpochMilli());//交货日期
                            }

                            if (Objects.nonNull(po.get("Price"))){
                                detail.put("numberField_m65wv558",new BigDecimal(getString(po.get("Price"))).doubleValue());//单价
                                detail.put("numberField_m65wv559",new BigDecimal(getString(po.get("TaxNetPrice"))).doubleValue());//含税单价
                            }
                            if (Objects.nonNull(po.get("DiscountRate"))){
                                detail.put("numberField_m65wv55a",new BigDecimal(getString(po.get("DiscountRate"))).doubleValue());//折扣率
                                detail.put("numberField_m65wv55b",new BigDecimal(getString(po.get("Discount"))).doubleValue());//折扣率
                            }
                            if (Objects.nonNull(po.get("TaxRate"))){
                                detail.put("numberField_m65wv55c",new BigDecimal(getString(po.get("TaxRate"))).doubleValue());//税率
                                detail.put("numberField_m65wv55d",new BigDecimal(getString(po.get("TaxAmount"))).doubleValue());//税额
                            }
                            detail.put("numberField_m65wv55e",new BigDecimal(getString(po.get("AllAmount"))).doubleValue());//价税合计
                            detail.put("numberField_m65wv55f",new BigDecimal(getString(po.get("Amount"))).doubleValue());//金额

                            details.add(detail);
                        }

                        formData.put("tableField_m65wv54z",details);

                        //新增数据
                        ydClient.operateData(YDParam.builder()
                                .formUuid("FORM-050FE2BED20644318C2521F9C7B8D9D1FIFO")
                                .formDataJson(JSONObject.toJSONString(formData))
                                .processCode("TPROC--MN866991XW7SZ5CI7GWSFB064DIQ2LEFUW56M1")
                                .build(), YDConf.FORM_OPERATION.start);
                    }
                }
            }
        }catch (Exception e){
            fail(e.getMessage());
        }



        return McR.success();
    }

    @Override
    public McR auditPurchaseOrder(Map map) {
        String code = getString(map.get("code"));
        try {
            K3CloudApi client = new K3CloudApi(initIden());
            String formId = "PUR_PurchaseOrder";

            Gson gson = new Gson();
            Audit audit = new Audit();

            audit.setNumbers(Collections.singletonList(code));

            //审核
            String resultJson = client.audit(formId,JSONObject.toJSONString(audit));
            RepoRet repoRet = gson.fromJson(resultJson, RepoRet.class);

            isTrue(repoRet);
        }catch (Exception e){
            fail(e.getMessage());
        }

        return McR.success();
    }

    @Override
    public McR syncSalePrice() {
        try {
            K3CloudApi client = new K3CloudApi(initIden());

            Gson gson = new Gson();

            String formId = "BD_SAL_PriceList";
            int startRow = 0;
            int limit = 2000;

            BillQuery billQuery = new BillQuery();

            billQuery.setLimit(limit);
            billQuery.setFormId(formId);
            billQuery.setFieldKeys("FNumber");
            List<Map> filterString = new ArrayList<>();
            //修改时间为昨天到今天
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FModifyDate","265","1","","","0"));
//            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FModifyDate","39","2025-03-06 00:00:00","","","0"));
            billQuery.setFilterString(filterString);

            List<Map> result = new ArrayList<>();
            List<Map> operatorList = new ArrayList<>();


            do {
                billQuery.setStartRow(startRow);
                String s = client.billQuery(JSONObject.toJSONString(billQuery));
                result = (List<Map>)JSONObject.parse(s);
                operatorList.addAll(result);

                startRow += limit;
            }while (result.size() == limit);

            for (Map operator : operatorList) {
                String fNumber = getString(operator.get("FNumber"));

                View view = new View();
                view.setNumber(fNumber);
                String resultJson2 = client.view(formId,JSONObject.toJSONString(view));

                RepoRet repoRet = gson.fromJson(resultJson2, RepoRet.class);
                if (isTrue(repoRet)) {
                    Map result2 = (Map) repoRet.getResult().getResult();

                    Map formData = new HashMap();

                    formData.put("textField_m7k2tk3u",getString(((List<Map>)result2.get("Name")).get(0).get("Value")));//名称
                    formData.put("textField_m7k2tk3t",getString(result2.get("Number")));//编号
                    formData.put("textField_m7k2tk3v",getMultiLanguageTextName(result2.get("CurrencyId")));//币别
                    formData.put("textField_m7lhqd0y",getEntryNumber(result2.get("CurrencyId")));//币别编码

                    Map salApplycustomer = ((List<Map>) result2.get("SAL_APPLYCUSTOMER")).get(0);

                    formData.put("textField_m7k314sr",getMultiLanguageTextName(salApplycustomer.get("CustID")));//客户名称
                    formData.put("textField_m7k314ss",getEntryNumber(salApplycustomer.get("CustID")));//客户编码
                    formData.put("textField_m7k2tk3z",(boolean) result2.get("IsIncludedTax") ? "是" : "否");//含税

                    List<Map> salPricelistentry = (List<Map>) result2.get("SAL_PRICELISTENTRY");

                    for (Map salPriceEntry : salPricelistentry) {
                        formData.put("textField_m7k2tk3x",getMultiLanguageTextName(salPriceEntry.get("MaterialId")));//物料名称
                        formData.put("textField_m7k2tk3w",getEntryNumber(salPriceEntry.get("MaterialId")));//物料编码

                        formData.put("textField_m7k2tk3y",getMultiLanguageTextName(salPriceEntry.get("PriceUnitId")));//计价单位
                        formData.put("textField_m7k314st",getEntryNumber(salPriceEntry.get("PriceUnitId")));//单位编码

                        formData.put("numberField_m7k2tk41",new BigDecimal(getString(salPriceEntry.get("Price"))));//价格

                        formData.put("textField_m7k2tk42",AUDITSTATUS.get(getString(salPriceEntry.get("RowAuditStatus"))));//审核状态
                        formData.put("textField_m7u4x3hr",FFORBIDSTATUS.get(getString(salPriceEntry.get("ForbidStatus"))));//失效


                        //新增数据
                        ydClient.operateData(YDParam.builder()
                                .formUuid("FORM-3B1E5298BA4644C1B994B81A4D986886YRA5")
                                .formDataJson(JSONObject.toJSONString(formData))
                                .searchCondition(JSONObject.toJSONString(UtilMap.map("textField_m7k2tk3t, textField_m7k2tk3w",getString(result2.get("Number")),getEntryNumber(salPriceEntry.get("MaterialId")))))
                                .useLatestVersion(true)
                                .build(), YDConf.FORM_OPERATION.upsert);
                    }

                }

            }
        }catch (Exception e){
            fail(e.getMessage());
        }

        return McR.success();
    }

    @Override
    public McR syncInspectionOrder() {
        try {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");

            //业务对象标识
            String formId = "QM_InspectBill";

            K3CloudApi client = new K3CloudApi(initIden());
            Gson gson = new Gson();

            //查询当天已审核且审核结果为不合格的数据
            BillQuery billQuery = new BillQuery();
            billQuery.setFormId(formId);
            billQuery.setFieldKeys("FBillNo");
            billQuery.setStartRow(0);
            billQuery.setLimit(2000);

            List<Map> filterString = new ArrayList<>();
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FInspectResult","29","2","","","0"));
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FDocumentStatus","105","C","","","0"));
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FApproveDate","13","","","","0"));//审核日期为今天
//            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FApproveDate","39","2025-03-10 00:00:00","","","0"));//审核日期大于2025-03-10 00:00:00
            billQuery.setFilterString(filterString);

            String resultJson = client.billQuery(JSONObject.toJSONString(billQuery));

            List<Map> list = (List<Map>) JSONObject.parse(resultJson);

            Set<String> fBillNoSet = new HashSet<>();

            for (Map map : list) {
                String fBillNo = getString(map.get("FBillNo"));

                if (!fBillNoSet.contains(fBillNo)){
                    fBillNoSet.add(fBillNo);
                }else {
                    continue;
                }

                //查询宜搭中是否已添加该检验单
                List<Map> data = (List<Map>) ydClient.queryData(YDParam.builder()
                        .formUuid("FORM-959B1CB0AF9F41A091DFDE1203D0C7B2FQBO")
                        .searchFieldJson(JSONObject.toJSONString(UtilMap.map("textField_m82j5zsd", fBillNo)))
                        .build(), YDConf.FORM_QUERY.retrieve_list).getData();

                if (data.isEmpty()){
                    View view = new View();
                    view.setNumber(fBillNo);
                    String resultJson2 = client.view(formId,JSONObject.toJSONString(view));
                    RepoRet repoRet = gson.fromJson(resultJson2, RepoRet.class);
                    if (isTrue(repoRet)){
                        Map result = (Map) repoRet.getResult().getResult();
                        Map formData = new HashMap();
                        formData.put("textField_m82j5zsd",fBillNo);//单据编号
                        formData.put("numberField_m86nmon3",result.get("Id"));//id
                        formData.put("textField_m82j5zse",getMultiLanguageTextName(result.get("FBillTypeID")));//单据类型
                        formData.put("textField_m82j5zsf",BUSINESS_TYPE.get(getString(result.get("BusinessType"))));//业务类型
                        // 解析字符串为 LocalDateTime
                        LocalDateTime localDateTime = LocalDateTime.parse(getString(result.get("FDate")), formatter);
                        // 将 LocalDateTime 转换为 ZonedDateTime
                        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
                        formData.put("dateField_m82j5zsk",zonedDateTime.toInstant().toEpochMilli());//单据日期
                        formData.put("textField_m82j5zsl",FDOCUMENTSTATUS.get(getString(result.get("DocumentStatus"))));//单据状态
                        if (!((List<Map>)result.get("Description")).isEmpty()){
                            formData.put("textareaField_m82j5zsm",((List<Map>)result.get("Description")).get(0).get("Value"));//描述
                        }
                        List<Map> entityList = (List<Map>) result.get("Entity");
                        List<Map> detailList = new ArrayList<>();
                        for (Map entity : entityList) {
                            Map detail = new HashMap();
                            detail.put("textField_m82j5zsp",getEntryNumber(entity.get("MaterialId")));//物料编码
                            detail.put("textField_m82j5zsr",getMultiLanguageTextSpecification(entity.get("MaterialId")));//规格型号
                            detail.put("textField_m82j5zsq",getMultiLanguageTextName(entity.get("MaterialId")));//物料名称
                            detail.put("textField_m82og859",getMultiLanguageTextName(entity.get("UnitId")));//单位
                            detail.put("textField_m82og85a",getEntryNumber(entity.get("UnitId")));//单位编码
                            detail.put("textField_m82qhpm0",getMultiLanguageTextName(entity.get("SupplierId")));//供应商
                            detail.put("textField_m82qhpm1",getEntryNumber(entity.get("SupplierId")));//供应商编码
                            detail.put("numberField_m82j5zst",entity.get("InspectQty"));//检验数量
                            detail.put("numberField_m82j5zsu",entity.get("QualifiedQty"));//合格数
                            detail.put("numberField_m82j5zsv",entity.get("UnqualifiedQty"));//不合格数
                            detail.put("textField_m82j5zsx",INSPECT_RESULT.get(getString(entity.get("InspectResult"))));//检验结果
                            detail.put("numberField_m873a1q2",entity.get("Id"));//分录明细id
                            if (!((List<Map>)entity.get("Memo")).isEmpty()){
                                detail.put("textField_m82j5zsz",((List<Map>)entity.get("Memo")).get(0).get("Value"));//不良原因
                            }

                            List<Map> policyDetail = (List<Map>) entity.get("PolicyDetail");
                            if (!policyDetail.isEmpty()){
                                detail.put("numberField_m8fkgsvo",policyDetail.get(0).get("Id"));//使用决策id
                            }

                            detailList.add(detail);
                        }
                        formData.put("tableField_m82j5zso",detailList);


                        //新增数据
                        ydClient.operateData(YDParam.builder()
                                .formUuid("FORM-959B1CB0AF9F41A091DFDE1203D0C7B2FQBO")
                                .formDataJson(JSONObject.toJSONString(formData))
                                .build(), YDConf.FORM_OPERATION.create);
                    }

                    /*else {
                        //更新数据
                        ydClient.operateData(YDParam.builder()
                                .formInstId(getString(data.get(0).get("formInstanceId")))
                                .updateFormDataJson(JSONObject.toJSONString(formData))
                                .useLatestVersion(true).build(), YDConf.FORM_OPERATION.update);
                    }*/
                }

            }
        }catch (Exception e){
            return McR.errorUnknown(e.getMessage());
        }

        return McR.success();
    }

    @Override
    public McR syncData() {
        log.info("-----------------开始同步金蝶业务数据-------------------------");

        syncCustomers();//同步客户
        syncSalesman();//同步业务员
        syncSupplier();//同步供应商
        syncSalePrice();//同步销售价目表
        syncMaterial();//同步物料

        //新增数据底表更新时间
        ydClient.operateData(YDParam.builder()
                .formUuid("FORM-5BAA6A050AC449438568D5A50FE2D2684RBN")
                .formDataJson(JSONObject.toJSONString(UtilMap.map("dateField_m8sdk1ny", new Date().getTime())))
                .build(), YDConf.FORM_OPERATION.create);

        log.info("-----------------金蝶业务数据同步完成-------------------------");

        return McR.success();
    }

    @Async
    @Override
    public void manualSyncData(String userId) {
        //发送工作通知
        if (Strings.isNotBlank(userId)){
            Map param2 = new HashMap();
            param2.put("access_token",ddClient.getAccessToken());
            Map body3 = new HashMap();
            body3.put("agent_id",ddConf.getAgentId());
            body3.put("userid_list",userId);
            Map msg = new HashMap();
            msg.put("msgtype","text");
            //获取当前时间 精确到秒
            String time = DateUtil.format(new Date(),"yyyy-MM-dd HH:mm:ss");
            msg.put("text", UtilMap.map("content","开始同步金蝶业务数据  时间：" + time));
            body3.put("msg",msg);
            UtilHttp.doPost("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2",null,param2,body3);
        }

        syncData();

        //发送工作通知
        if (Strings.isNotBlank(userId)){
            Map param2 = new HashMap();
            param2.put("access_token",ddClient.getAccessToken());
            Map body3 = new HashMap();
            body3.put("agent_id",ddConf.getAgentId());
            body3.put("userid_list",userId);
            Map msg = new HashMap();
            msg.put("msgtype","text");
            //获取当前时间 精确到秒
            String time = DateUtil.format(new Date(),"yyyy-MM-dd HH:mm:ss");
            msg.put("text", UtilMap.map("content","金蝶业务数据已更新  时间：" + time));
            body3.put("msg",msg);
            UtilHttp.doPost("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2",null,param2,body3);
        }
    }

    @Override
    public void manualSyncMaterialData(String userId,String startTime,String endTime) {
        //发送工作通知
        if (Strings.isNotBlank(userId)){
            Map param2 = new HashMap();
            param2.put("access_token",ddClient.getAccessToken());
            Map body3 = new HashMap();
            body3.put("agent_id",ddConf.getAgentId());
            body3.put("userid_list",userId);
            Map msg = new HashMap();
            msg.put("msgtype","text");
            //获取当前时间 精确到秒
            String time = DateUtil.format(new Date(),"yyyy-MM-dd HH:mm:ss");
            msg.put("text", UtilMap.map("content","开始同步金蝶物料数据  时间：" + time));
            body3.put("msg",msg);
            UtilHttp.doPost("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2",null,param2,body3);
        }

        try {
            K3CloudApi client = new K3CloudApi(initIden());

            List<Map> result = new ArrayList<>();
            List<Map> materialList = new ArrayList<>();

            int startRow = 0;
            int limit = 2000;

            BillQuery billQuery = new BillQuery();
            billQuery.setFormId("BD_MATERIAL");
            billQuery.setFieldKeys("FUseOrgId,FNumber,FName,FSpecification,FDocumentStatus,FForbidStatus,FErpClsID,FBaseUnitId,FRefStatus");
            List<Map> filterString = new ArrayList<>();

            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FCreateDate","39",startTime,"","","0"));//创建日期大于等于xx
            filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FCreateDate","16",endTime,"","","0"));//创建日期小于等于xx

            billQuery.setFilterString(filterString);
            billQuery.setLimit(limit);
            do {
                billQuery.setStartRow(startRow);
                String s = client.billQuery(JSONObject.toJSONString(billQuery));
                result = (List<Map>)JSONObject.parse(s);
                materialList.addAll(result);

                startRow += limit;
            }while (result.size() == limit);

            for (Map material : materialList) {
                Map formData = new HashMap();
                formData.put("textField_m6ak640p",material.get("FUseOrgId"));//使用组织
                formData.put("textField_m6ak640v",material.get("FNumber"));//编码
                formData.put("selectField_m83u6et1",getString(material.get("FNumber")).substring(0,1).equals("C") ? "成品" : "配件");
                formData.put("textField_m6ak640w",material.get("FName"));//名称
                formData.put("textField_m6ak640x",material.get("FSpecification"));//规格型号
                formData.put("textField_m6ak6413",FDOCUMENTSTATUS.get(material.get("FDocumentStatus").toString()));//单据状态
                formData.put("textField_m6ak6414",FFORBIDSTATUS.get(material.get("FForbidStatus").toString()));//禁用状态
                formData.put("textField_m6ak6415",FERPCLSID.get(material.get("FErpClsID").toString()));//物料属性
                formData.put("textField_m6ak641c",material.get("FRefStatus"));//已使用

                //查找计量单位信息
                String FBaseUnitId = material.get("FBaseUnitId").toString();
                View view = new View();
                view.setId(FBaseUnitId);
                String resultJson = client.view("BD_UNIT", JSONObject.toJSONString(view));
                Gson gson = new Gson();
                RepoRet repoRet = gson.fromJson(resultJson, RepoRet.class);
                if (isTrue(repoRet)){
                    Map unitInfo = (Map) repoRet.getResult().getResult();
                    String unitName = ((List<Map>) unitInfo.get("Name")).get(0).get("Value").toString();

                    String unitCode = unitInfo.get("Number").toString();

                    formData.put("textField_m6ak6416",unitName);//基本单位
                    formData.put("textField_m6ak641d",unitCode);//单位编码
                }


                ydClient.operateData(YDParam.builder()
                        .formUuid("FORM-2A5CAB7EB91D493AAFC90D8C7479A7F5KPR7")
                        .searchFieldJson(JSONObject.toJSONString(Arrays.asList(new YDSearch("textField_m6ak640v",material.get("FNumber"),"编码", YDSearch.Type.TEXT_FIELD,YDSearch.Operator.EQ))))
                        .formDataJson(JSONObject.toJSONString(formData))
                        .build(), YDConf.FORM_OPERATION.upsert);

            }
        }catch (Exception e){
            fail(e.getMessage());
        }

        //新增数据底表更新时间
        ydClient.operateData(YDParam.builder()
                .formUuid("FORM-5BAA6A050AC449438568D5A50FE2D2684RBN")
                .formDataJson(JSONObject.toJSONString(UtilMap.map("dateField_m8sdk1ny", new Date().getTime())))
                .build(), YDConf.FORM_OPERATION.create);

        //发送工作通知
        if (Strings.isNotBlank(userId)){
            Map param2 = new HashMap();
            param2.put("access_token",ddClient.getAccessToken());
            Map body3 = new HashMap();
            body3.put("agent_id",ddConf.getAgentId());
            body3.put("userid_list",userId);
            Map msg = new HashMap();
            msg.put("msgtype","text");
            //获取当前时间 精确到秒
            String time = DateUtil.format(new Date(),"yyyy-MM-dd HH:mm:ss");
            msg.put("text", UtilMap.map("content","金蝶物料数据已更新  时间：" + time));
            body3.put("msg",msg);
            UtilHttp.doPost("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2",null,param2,body3);
        }
    }


    private String getMultiLanguageTextName(Object object){
        if (Objects.nonNull(object)){
            Map map = (Map) object;
            List<Map> multiLanguageText = (List<Map>) map.get("MultiLanguageText");
            String value = getString(multiLanguageText.get(0).get("Name"));

            return value;
        }
        return null;
    }

    private String getMultiLanguageTextSpecification(Object object){
        if (Objects.nonNull(object)){
            Map map = (Map) object;
            List<Map> multiLanguageText = (List<Map>) map.get("MultiLanguageText");
            String value = getString(multiLanguageText.get(0).get("Specification"));

            return value;
        }
        return null;
    }

    private String getEntryNumber(Object object){
        if (Objects.nonNull(object)){
            Map map = (Map) object;
            String value =  getString(map.get("Number"));

            return value;
        }
        return null;
    }


    private boolean isTrue(RepoRet repoRet){
        Gson gson = new Gson();

        if (repoRet.getResult().getResponseStatus().isIsSuccess()) {
            System.out.printf("接口返回结果: %s%n", gson.toJson(repoRet.getResult()));
            return true;
        } else {
            fail("接口返回结果: " + gson.toJson(repoRet.getResult().getResponseStatus()));
            return false;
        }
    }

    private List<Map> getYdFormDataList(String formUuid, String searchCondition, YDConf.FORM_QUERY formQuery) {
        List<Map> list = new ArrayList<>();
        DDR_New ddrNew = new DDR_New();
        int pageNumber = 1;
        int pageSize = 100;
        do {
            ddrNew = ydClient.queryData(YDParam.builder().formUuid(formUuid)
                    .searchCondition(searchCondition)
                    .pageNumber(pageNumber)
                    .pageSize(pageSize).build(), formQuery);

            list.addAll((List<Map>) ddrNew.getData());
            pageNumber++;
        }while (ddrNew.getTotalCount() > ddrNew.getPageNumber() * pageSize);
        return list;
    }


}
