package com.malk.jinlun.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.kingdee.bos.webapi.entity.IdentifyInfo;
import com.kingdee.bos.webapi.sdk.K3CloudApi;
import com.malk.jinlun.config.KDWebApiConf;
import com.malk.jinlun.entity.BillQuery;
import com.malk.jinlun.service.CpClient;
import com.malk.jinlun.service.JinlunTaskService;
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.stereotype.Service;

import java.util.*;

@Slf4j
@Service
public class JinlunTaskServiceImpl implements JinlunTaskService {
    @Autowired
    private KDWebApiConf kdWebApiConf;

    @Autowired
    private CpClient cpClient;

    @Override
    public void syncMaterial() {
        log.info("开始同步物料数据");
        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("FNumber,FName,F_Sl_xingnengid.FName,F_Sl_cihuaid.FName,FSpecification,FErpClsID,F_Sl_xingzhuangid.FName,F_Sl_ducengid.FName,F_Sl_ischongciid.FName,F_Sl_chihuaguige,F_Sl_midu,F_Sl_guige,F_Sl_weight,F_Sl_ischeck,F_Sl_qianguige,F_Sl_cixiangchang,F_NLD_gongyi.FName,F_Sl_biaomianji,FMaterialGroup.FName,FCategoryID.FName,FVOLUME,FBaseUnitId.FName,FSaleUnitId.FName,FSalePriceUnitId.FName");
        List<Map> filterString = new ArrayList<>();

        //审核日期为昨天至今天
        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FApproveDate","265",1,"","","0"));//审核日期在今天之前N天以后
//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FApproveDate","420","2024-10-20 00:00:00","","","0"));//审核日期年=XX
//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FNumber","67","35","","","0"));//物料编码等于XX


        billQuery.setFilterString(filterString);
        billQuery.setLimit(limit);

        do {
            billQuery.setStartRow(startRow);
            String s = null;

            try {
                s = client.billQuery(JSONObject.toJSONString(billQuery));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            result = (List<Map>)JSONObject.parse(s);
            materialList.addAll(result);

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

        for (Map map : materialList) {
            Map data = new HashMap();
            data.put("ShortText1757932581400",UtilMap.getString(map,"FName"));//物料名称
            data.put("ShortText1757932557449",UtilMap.getString(map,"FNumber"));//物料编码
            data.put("ShortText1757932601205",UtilMap.getString(map,"F_Sl_xingnengid.FName"));//性能
            data.put("ShortText1757932616477",UtilMap.getString(map,"F_Sl_cihuaid.FName"));//磁化方向
            data.put("ShortText1757932652570",UtilMap.getString(map,"F_Sl_xingzhuangid.FName"));//形状
            data.put("ShortText1757932660567",UtilMap.getString(map,"F_Sl_ducengid.FName"));//镀层
            data.put("Dropdown1757932715739",UtilMap.getString(map,"F_Sl_ischongciid.FName"));//是否充磁
            data.put("ShortText1757932699628",UtilMap.getString(map,"F_Sl_chihuaguige"));//磁化规格
            data.put("Number1757932755471",UtilMap.getDouble(map,"F_Sl_midu"));//密度(g/mm³)
            data.put("ShortText1757932739089",UtilMap.getString(map,"F_Sl_guige"));//尺寸规格
            data.put("Number1757932746124",UtilMap.getDouble(map,"F_Sl_weight"));//单重(kg)
            data.put("Logic1757932804393",UtilMap.getBoolean(map,"F_Sl_ischeck"));//是否需要检验
            data.put("ShortText1757932821074",UtilMap.getString(map,"F_Sl_qianguige"));//带前后缀规格
            data.put("Number1757932837126",UtilMap.getDouble(map,"F_Sl_cixiangchang"));//磁向长
            data.put("ShortText1757932874077",UtilMap.getString(map,"F_NLD_gongyi.FName"));//工序
            data.put("Number1757932881710",UtilMap.getDouble(map,"F_Sl_biaomianji"));//表面积
            data.put("ShortText1760342223781",UtilMap.getString(map,"FSpecification"));//规格型号
            data.put("ShortText1757933029016",UtilMap.getString(map,"FMaterialGroup.FName"));//物料分组
            data.put("ShortText1757933017962",UtilMap.getString(map,"FCategoryID.FName"));//存货类别

            String fErpClsID = UtilMap.getString(map, "FErpClsID");
            String wlsx = "";
            switch (fErpClsID){
                case "10":wlsx = "资产";break;
                case "9":wlsx = "配置";break;
                case "2":wlsx = "自制";break;
                case "11":wlsx = "费用";break;
                case "12":wlsx = "模型";break;
                case "5":wlsx = "虚拟";break;
                case "7":wlsx = "一次性";break;
                case "13":wlsx = "产品系列";break;
                case "3":wlsx = "委外";break;
                case "4":wlsx = "特征";break;
                case "6":wlsx = "服务";break;
                case "1":wlsx = "原材料";break;

            }
            data.put("ShortText1757933048314",wlsx);//物料属性

            data.put("Number1757933060744",UtilMap.getDouble(map,"FVOLUME"));//体积
            data.put("ShortText1757933079170",UtilMap.getString(map,"FBaseUnitId.FName"));//基本单位
            data.put("Text1760411136055",UtilMap.getString(map,"FSaleUnitId.FName"));//销售单位
            data.put("Text1760411137275",UtilMap.getString(map,"FSalePriceUnitId.FName"));//销售计价单位

            String schemaCode = "WL";

            //查询是否存在
            Map result2 = cpClient.getCpBoList(schemaCode, UtilMap.map("queryFilterType, propertyCode, propertyValue", "Eq", "ShortText1757932557449", UtilMap.getString(map,"FNumber")),null, 0, 1, null);

            Map bizObjectPage = UtilMap.getMap(UtilMap.getMap(result2, "data"),"bizObjectPage");

            int totalElements = UtilMap.getInt(bizObjectPage, "totalElements");

            if (totalElements > 0) {
                //云枢更新物料
                Map content = ((List<Map>) UtilMap.getList(bizObjectPage, "content")).get(0);

                String bizObjectId = UtilMap.getString(content,"bizObjectId");//主表实例id

                data.put("id",bizObjectId);

                Map result3 = cpClient.updateCpBo(schemaCode, data,null);
            }else {
                //云枢新增物料
                Map result3 = cpClient.createCpBo(schemaCode, data,null);
            }
        }
    }

    @Override
    public void syncSaleOut() {
        log.info("开始同步销售出库单数据");
        K3CloudApi client = new K3CloudApi(initIden());

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

        int startRow = 0;
        int limit = 2000;

        BillQuery billQuery = new BillQuery();
        billQuery.setFormId("SAL_OUTSTOCK");
        billQuery.setFieldKeys("FBillNo,FBillTypeID.FName,FDate,FSettleCurrID.FName,FCustomerID.FName,FCustomerID.FShortName,FCustomerID.FNumber,FHeadLocationID.FName,F_VMKV_Text,FMaterialID.FNumber,FMaterialID.FName,FMaterialID.FSpecification,FMaterialID.F_Sl_ducengid,F_VMKV_Text_WLZT,FPriceUnitQty,FRealQty,FUnitID.FName,FPriceUnitId.FName,FAuxUnitID.FName,FAuxUnitQty,FIsFree,FPrice,FTaxPrice,FEntryTaxRate,FAmount,FAllAmount,FDiscount,FEntrynote,FSrcBillNo");
        List<Map> filterString = new ArrayList<>();

        //审核日期为昨天至今天
        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FApproveDate","265",1,"","","0"));//审核日期在今天之前N天以后
//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FApproveDate","420","2026-01-01 00:00:00","","","0"));//审核日期年=XX
//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FNumber","67","35","","","0"));//物料编码等于XX


        billQuery.setFilterString(filterString);
        billQuery.setLimit(limit);

        do {
            billQuery.setStartRow(startRow);
            String s = null;

            try {
                s = client.billQuery(JSONObject.toJSONString(billQuery));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            result = (List<Map>)JSONObject.parse(s);
            saleOutList.addAll(result);

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


        List<Map<String,Object>> dataList = new ArrayList<>();

        for (Map saleOut : saleOutList) {
            Map data = new HashMap();

            data.put("ShortText1760153678207",UtilMap.getString(saleOut,"FBillNo"));//单据编号
            data.put("ShortText1760153685839",UtilMap.getString(saleOut,"FBillTypeID.FName"));//单据类型
            data.put("Date1760153694040",UtilMap.getString(saleOut, "FDate").replace("T"," "));//日期
            data.put("ShortText1760153691233",UtilMap.getString(saleOut,"FSettleCurrID.FName"));//结算币别
            data.put("ShortText1760153707273",UtilMap.getString(saleOut,"FCustomerID.FName"));//客户名称
            data.put("ShortText1760153714871",UtilMap.getString(saleOut,"FCustomerID.FShortName"));//客户简称
            data.put("ShortText1768439848740",UtilMap.getString(saleOut,"FCustomerID.FNumber"));//客户简称
            data.put("ShortText1760153722192",UtilMap.getString(saleOut,"FHeadLocationID.FName"));//交货地点
            data.put("ShortText1781506895192",UtilMap.getString(saleOut,"F_VMKV_Text"));//客户流水号
            data.put("ShortText1781506978470",UtilMap.getString(saleOut,"FSrcBillNo"));//销售订单编号

            List<Map> entry = new ArrayList<>();
            Map entryMap = new HashMap();
            entryMap.put("Number1760153738400",UtilMap.getString(saleOut,"FMaterialID.FNumber"));//物料编码
            entryMap.put("ShortText1760153773163",UtilMap.getString(saleOut,"FMaterialID.FNumber"));//物料编码
            entryMap.put("Text1760153778635",UtilMap.getString(saleOut,"FMaterialID.FName"));//物料名称
            entryMap.put("Text1760153786986",UtilMap.getString(saleOut,"FMaterialID.FSpecification"));//规格型号
            entryMap.put("ShortText1762245895776",UtilMap.getString(saleOut,"FMaterialID.F_Sl_ducengid"));//镀锌
            entryMap.put("Text1762245901183",UtilMap.getString(saleOut,"F_VMKV_Text_WLZT"));//物料状态

            entryMap.put("Number1760153811668",UtilMap.getDouble(saleOut,"FPriceUnitQty"));//计价数量
            Double sfsl = UtilMap.getDouble(saleOut, "FRealQty");
            entryMap.put("Number1760153958907", sfsl);//实发数量
            entryMap.put("Text1760153793403",UtilMap.getString(saleOut,"FPriceUnitId.FName"));//计价单位
            String kcdw = UtilMap.getString(saleOut, "FUnitID.FName");
            entryMap.put("ShortText1762508609328", kcdw);//库存单位
            entryMap.put("Text1762508629987",UtilMap.getString(saleOut,"FAuxUnitID.FName"));//库存辅单位
            Double kcfdwsl = UtilMap.getDouble(saleOut, "FAuxUnitQty");
            entryMap.put("Number1762508641763", kcfdwsl);//库存辅单位数量
            entryMap.put("Logic1760171983887",UtilMap.getBoolean(saleOut,"FIsFree"));//是否赠品
            entryMap.put("Number1760153991898",UtilMap.getDouble(saleOut,"FPrice"));//单价
            entryMap.put("Number1760154006703",UtilMap.getDouble(saleOut,"FTaxPrice"));//计价单价
            entryMap.put("ShortText1785228303666",UtilMap.getDouble(saleOut,"FTaxPrice").toString());//单价文本
            entryMap.put("Number1762225120251",UtilMap.getDouble(saleOut,"FEntryTaxRate"));//税率
            entryMap.put("ShortText1785228889353",UtilMap.getDouble(saleOut,"FEntryTaxRate").toString());//税率文本
            entryMap.put("Number1760154034052",UtilMap.getDouble(saleOut,"FAmount"));//金额
            entryMap.put("Number1760154039959",UtilMap.getDouble(saleOut,"FAllAmount"));//价税合计
            entryMap.put("Number1760154058940",UtilMap.getDouble(saleOut,"FDiscount"));//折扣额
            entryMap.put("ShortText1760154066042",UtilMap.getString(saleOut,"FEntrynote"));//备注

            if ("Pcs".equals(kcdw)){
                entryMap.put("Number1762509492431",sfsl);//数量
                entryMap.put("Number1762509515885",kcfdwsl);//重量
            }else {
                entryMap.put("Number1762509492431",0);//数量
                entryMap.put("Number1762509515885",sfsl);//重量
            }
            entryMap.put("rowStatus","Added");

            entry.add(entryMap);

            data.put("Sheet1760153734916",entry);

            dataList.add(data);
        }

        //处理同一出库单多个明细
        List<Map<String, Object>> list = mergeListMap(dataList, "ShortText1760153678207", "Sheet1760153734916");

        for (Map<String, Object> map : list) {
            String schemaCode = "XSCKD";
            //查询是否存在
            Map result2 = cpClient.getCpBoList(schemaCode, UtilMap.map("queryFilterType, propertyCode, propertyValue", "Eq", "ShortText1760153678207", UtilMap.getString(map, "ShortText1760153678207")),null, 0, 1, null);

            Map bizObjectPage = UtilMap.getMap(UtilMap.getMap(result2, "data"),"bizObjectPage");

            int totalElements = UtilMap.getInt(bizObjectPage, "totalElements");

            List<Map> items = (List<Map>) map.get("Sheet1760153734916");
            if (totalElements > 0) {
                //云枢更新销售出库单
                Map content = ((List<Map>) UtilMap.getList(bizObjectPage, "content")).get(0);

                Map map1 = UtilMap.getMap(content, "data");
                List<Map> list1 = UtilMap.getList(map1, "Sheet1760153734916");

                //原子表删除  覆盖更新
                for (Map map2 : list1) {
                    String id = UtilMap.getString(map2, "id");
                    items.add(UtilMap.map("id, rowStatus", id,"Deleted"));
                }

                String bizObjectId = UtilMap.getString(content,"bizObjectId");//主表实例id

                map.put("id",bizObjectId);

                Map result3 = cpClient.updateCpBo(schemaCode, map,null);
            }else {
                //云枢新增销售出库单
                items.forEach(item -> item.put("rowStatus", "added"));
                Map result3 = cpClient.createCpBo(schemaCode, map,null);
            }
        }
    }

    @Override
    public void syncReceipt() {
        log.info("开始同步收款单数据");
        K3CloudApi client = new K3CloudApi(initIden());

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

        int startRow = 0;
        int limit = 2000;

        BillQuery billQuery = new BillQuery();
        billQuery.setFormId("AR_RECEIVEBILL");
        billQuery.setFieldKeys("FBillNo,FBillTypeID.FName,FPAYUNITTYPE,FDate,FPAYUNIT.FName,FCURRENCYID.FName,FRECEIVEAMOUNTFOR_H,FRECEIVEAMOUNT_H,FREALRECAMOUNTFOR,FREALRECAMOUNT_H,F_VMKV_Combo,FSALEERID.FName,F_VMKV_Base_83g.FName,FSETTLETYPEID,FSETTLETYPEID.FName,FPURPOSEID.FName,FACCOUNTID.FNumber,FACCOUNTID.FName,FRECTOTALAMOUNTFOR,FRECTOTALAMOUNT,FREALRECAMOUNTFOR_D,FREALRECAMOUNT_D,FCOMMENT");
        List<Map> filterString = new ArrayList<>();

        //审核日期为昨天至今天
        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FApproveDate","265",1,"","","0"));//审核日期在今天之前N天以后
//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FApproveDate","420","2025-10-20 00:00:00","","","0"));//审核日期年=XX
//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FApproveDate","39","2026-01-01 00:00:00","","","0"));//审核日期>=XX
//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FNumber","67","35","","","0"));//物料编码等于XX


        billQuery.setFilterString(filterString);
        billQuery.setLimit(limit);

        do {
            billQuery.setStartRow(startRow);
            String s = null;

            try {
                s = client.billQuery(JSONObject.toJSONString(billQuery));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            result = (List<Map>)JSONObject.parse(s);
            receiptList.addAll(result);

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


        List<Map<String,Object>> dataList = new ArrayList<>();

        for (Map receipt : receiptList) {
            Map data = new HashMap();

            data.put("ShortText1760585125989",UtilMap.getString(receipt,"FBillNo"));//单据编号
            data.put("ShortText1760585107833",UtilMap.getString(receipt,"FBillTypeID.FName"));//单据类型
            data.put("Date1760585187315",UtilMap.getString(receipt, "FDate").replace("T"," "));//业务日期
            data.put("Text1760585197637",UtilMap.getString(receipt,"FSALEERID.FName"));//销售员
            data.put("ShortText1760585145727",UtilMap.getString(receipt,"F_VMKV_Base_83g.FName"));//跟单员
            data.put("ShortText1760585132200",UtilMap.getString(receipt,"FPAYUNIT.FName"));//付款单位

            String FPAYUNITTYPE = UtilMap.getString(receipt, "FPAYUNITTYPE");
            String FPAYUNITTYPE_VALUE = "";
            switch (FPAYUNITTYPE){
                case "BD_Supplier" : FPAYUNITTYPE_VALUE = "供应商";break;
                case "BD_Customer" : FPAYUNITTYPE_VALUE = "客户";break;
                case "BD_Department" : FPAYUNITTYPE_VALUE = "部门";break;
                case "BD_Empinfo" : FPAYUNITTYPE_VALUE = "员工";break;
                case "FIN_OTHERS" : FPAYUNITTYPE_VALUE = "其他往来单位";break;
                case "ORG_Organizations" : FPAYUNITTYPE_VALUE = "组织机构";break;
                case "BD_BANK" : FPAYUNITTYPE_VALUE = "银行";break;
                default:break;
            }
            data.put("ShortText1760585114989", FPAYUNITTYPE_VALUE);//付款单位类型

            data.put("ShortText1760585150625",UtilMap.getString(receipt,"FCURRENCYID.FName"));//币别

            String F_VMKV_Combo = UtilMap.getString(receipt, "F_VMKV_Combo");
            String F_VMKV_Combo_VALUE = "";
            switch (F_VMKV_Combo){
                case "ART" : F_VMKV_Combo_VALUE = "佳丰";break;
                case "JLCC" : F_VMKV_Combo_VALUE = "金轮";break;
                case "NOT" : F_VMKV_Combo_VALUE = "暂不确定";break;
                default:break;
            }
            data.put("ShortText1760585157387", F_VMKV_Combo_VALUE);//佳丰/金轮

            data.put("Number1760585167781",UtilMap.getDouble(receipt,"FRECEIVEAMOUNTFOR_H"));//应收金额
            data.put("Number1780280013419",UtilMap.getDouble(receipt,"FRECEIVEAMOUNT_H"));//应收金额（本位币）
            data.put("Number1760585178357",UtilMap.getDouble(receipt,"FREALRECAMOUNTFOR"));//实收金额
            data.put("Number1780280020461",UtilMap.getDouble(receipt,"FREALRECAMOUNT_H"));//实收金额（本位币）

            List<Map> entry = new ArrayList<>();
            Map entryMap = new HashMap();
            entryMap.put("ShortText1760585209233",UtilMap.getString(receipt,"FSETTLETYPEID.FName"));//结算方式
            entryMap.put("ShortText1760585224298",UtilMap.getString(receipt,"FPURPOSEID.FName"));//收款用途
            entryMap.put("ShortText1760585384491",UtilMap.getString(receipt,"FACCOUNTID.FNumber"));//我方银行账户
            entryMap.put("Text1760585393271",UtilMap.getString(receipt,"FACCOUNTID.FName"));//我方账户名称
            entryMap.put("Number1760585235219",UtilMap.getDouble(receipt,"FRECTOTALAMOUNTFOR"));//应收金额
            entryMap.put("Number1780280005945",UtilMap.getDouble(receipt,"FRECTOTALAMOUNT"));//应收金额（本位币）
            entryMap.put("Number1760585242849",UtilMap.getDouble(receipt,"FREALRECAMOUNTFOR_D"));//实收金额
            entryMap.put("Number1780279984172",UtilMap.getDouble(receipt,"FREALRECAMOUNT_D"));//实收金额（本位币）
            entryMap.put("ShortText1760585258640",UtilMap.getString(receipt,"FCOMMENT"));//备注
            entryMap.put("rowStatus","Added");

            entry.add(entryMap);

            data.put("Sheet1760585205663",entry);

            dataList.add(data);
        }

        //处理同一收款单多个明细
        List<Map<String, Object>> list = mergeListMap(dataList, "ShortText1760585125989", "Sheet1760585205663");

        for (Map<String, Object> map : list) {
            String schemaCode = "SKD";
            //查询是否存在
            Map result2 = cpClient.getCpBoList(schemaCode, UtilMap.map("queryFilterType, propertyCode, propertyValue", "Eq", "ShortText1760585125989", UtilMap.getString(map, "ShortText1760585125989")),null, 0, 1, null);

            Map bizObjectPage = UtilMap.getMap(UtilMap.getMap(result2, "data"),"bizObjectPage");

            int totalElements = UtilMap.getInt(bizObjectPage, "totalElements");

            List<Map> items = (List<Map>) map.get("Sheet1760585205663");
            if (totalElements > 0) {
                //云枢更新收款单
                Map content = ((List<Map>) UtilMap.getList(bizObjectPage, "content")).get(0);

                Map map1 = UtilMap.getMap(content, "data");
                List<Map> list1 = UtilMap.getList(map1, "Sheet1760585205663");

                //原子表删除  覆盖更新
                for (Map map2 : list1) {
                    String id = UtilMap.getString(map2, "id");
                    items.add(UtilMap.map("id, rowStatus", id,"Deleted"));
                }

                String bizObjectId = UtilMap.getString(content,"bizObjectId");//主表实例id

                map.put("id",bizObjectId);

                Map result3 = cpClient.updateCpBo(schemaCode, map,null);
            }else {
                //云枢新增收款单
                Map result3 = cpClient.createCpBo(schemaCode, map,null);
            }
        }
    }

    @Override
    public void syncReceivable() {
        log.info("开始同步应收单数据");
        K3CloudApi client = new K3CloudApi(initIden());

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

        int startRow = 0;
        int limit = 2000;

        BillQuery billQuery = new BillQuery();
        billQuery.setFormId("AR_receivable");
        billQuery.setFieldKeys("FBillTypeID.FName,FBillNo,FCUSTOMERID.FName,FSALEERID.FName,F_VMKV_Base_qtr.FName,FSetAccountType,FCURRENCYID.FName,FDate,FENDDATE_H,FPayConditon.FName,FALLAMOUNTFOR,FALLAMOUNT,FEntityDetail_FEntryID,FMATERIALID.FNumber,FMATERIALID.FName,FMATERIALID.F_Sl_xingnengid,FPRICEUNITID.FName,FPriceQty,FStockUnitId.FName,FStockQty,FSalUnitId.FName,FSalQty,FTaxPrice,FPrice,FEntryTaxRate,FNoTaxAmountFor_D,FTAXAMOUNTFOR_D,FALLAMOUNTFOR_D,FALLAMOUNT_D,FIsFree,FLot.FName,FRECEIVEAMOUNT,FComment,FSOURCEBILLNO");
        List<Map> filterString = new ArrayList<>();

        //审核日期为昨天至今天
        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FApproveDate","265",1,"","","0"));//审核日期在今天之前N天以后
        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FSetAccountType","29","2","","","0"));//立账类型等于暂估应收
//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FApproveDate","39","2026-06-01 00:00:00","","","0"));//审核日期大于等于XX
//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FApproveDate","16","2026-06-30 00:00:00","","","0"));//审核日期小于等于XX


//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FAPPROVEDATE","420","2025-10-21 00:00:00","","","0"));//审核日期年=XX
//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FDATE","420","2025-10-21 00:00:00","","","0"));//业务日期年=XX

        billQuery.setFilterString(filterString);
        billQuery.setLimit(limit);

        do {
            billQuery.setStartRow(startRow);
            String s = null;

            try {
                s = client.billQuery(JSONObject.toJSONString(billQuery));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            result = (List<Map>)JSONObject.parse(s);
            receiptList.addAll(result);

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


        List<Map<String,Object>> dataList = new ArrayList<>();

        for (Map receipt : receiptList) {
            Map data = new HashMap();

            data.put("ShortText1760602123650",UtilMap.getString(receipt,"FBillNo"));//发票号码
            data.put("ShortText1760602106521",UtilMap.getString(receipt,"FBillTypeID.FName"));//单据类型
            data.put("Date1760602205733",UtilMap.getString(receipt, "FDate").replace("T"," "));//业务日期
            data.put("ShortText1760602136864",UtilMap.getString(receipt,"FSALEERID.FName"));//销售员
            data.put("Text1760602141164",UtilMap.getString(receipt,"F_VMKV_Base_qtr.FName"));//跟单员
            data.put("ShortText1760602119316",UtilMap.getString(receipt,"FCUSTOMERID.FName"));//客户

            String FSetAccountType = UtilMap.getString(receipt, "FSetAccountType");
            String FSetAccountType_VALUE = "";
            switch (FSetAccountType){
                case "1" : FSetAccountType_VALUE = "业务应收";break;
                case "3" : FSetAccountType_VALUE = "财务应收";break;
                case "2" : FSetAccountType_VALUE = "暂估应收";break;
                default:break;
            }

            data.put("ShortText1760602147441", FSetAccountType_VALUE);//立账类型

            data.put("ShortText1760602218380",UtilMap.getString(receipt,"FPayConditon.FName"));//收款条件
            data.put("ShortText1760602197718",UtilMap.getString(receipt,"FCURRENCYID.FName"));//币别
            data.put("Number1760602528131",UtilMap.getDouble(receipt,"FALLAMOUNTFOR"));//价税合计
            data.put("Number1780278294305",UtilMap.getDouble(receipt,"FALLAMOUNT"));//价税合计（本位币）
            data.put("Date1760602209998",UtilMap.getString(receipt,"FENDDATE_H").replace("T"," "));//到期日
            data.put("ShortText1781506154858",UtilMap.getString(receipt,"FSOURCEBILLNO"));//销售出库单编号

            List<Map> entry = new ArrayList<>();
            Map entryMap = new HashMap();
            entryMap.put("ShortText1760605881791",UtilMap.getString(receipt,"FEntityDetail_FEntryID"));//分录ID
            entryMap.put("ShortText1760602287318",UtilMap.getString(receipt,"FMATERIALID.FNumber"));//物料编码
            entryMap.put("Text1760602292846",UtilMap.getString(receipt,"FMATERIALID.FName"));//物料名称
            entryMap.put("Text1760602314150",UtilMap.getString(receipt,"FMATERIALID.F_Sl_xingnengid"));//性能
            String jjdw = UtilMap.getString(receipt, "FPRICEUNITID.FName");
            entryMap.put("Text1760602299878", jjdw);//计价单位
            Double jjsl = UtilMap.getDouble(receipt, "FPriceQty");
            entryMap.put("Number1760602320518", jjsl);//计价数量
            String kcdw = UtilMap.getString(receipt, "FStockUnitId.FName");
            entryMap.put("Text1762914941284", kcdw);//库存单位
            Double kcsl = UtilMap.getDouble(receipt, "FStockQty");
            entryMap.put("Number1762914960910", kcsl);//库存数量
            String xsdw = UtilMap.getString(receipt, "FSalUnitId.FName");
            entryMap.put("Text1762914943634", xsdw);//销售单位
            Double xssl = UtilMap.getDouble(receipt, "FSalQty");
            entryMap.put("Number1762914972786", xssl);//销售数量
            entryMap.put("Number1760602330651",UtilMap.getDouble(receipt,"FTaxPrice"));//含税单价
            entryMap.put("Number1760602338551",UtilMap.getDouble(receipt,"FPrice"));//单价
            entryMap.put("Number1760602343876",UtilMap.getDouble(receipt,"FEntryTaxRate"));//税率
            entryMap.put("Number1760602347414",UtilMap.getDouble(receipt,"FNoTaxAmountFor_D"));//不含税金额
            entryMap.put("Number1760602354115",UtilMap.getDouble(receipt,"FTAXAMOUNTFOR_D"));//税额
            entryMap.put("Number1760602359012",UtilMap.getDouble(receipt,"FALLAMOUNTFOR_D"));//价税合计
            entryMap.put("Number1780278586837",UtilMap.getDouble(receipt,"FALLAMOUNT_D"));//价税合计（本位币）
            entryMap.put("Logic1760602369561",UtilMap.getString(receipt,"FIsFree"));//是否赠品

            entryMap.put("ShortText1760602387059",UtilMap.getString(receipt,"FLot.FName"));//批号
            entryMap.put("Number1760602396337",UtilMap.getDouble(receipt,"FRECEIVEAMOUNT"));//已结算金额
            entryMap.put("Text1760602391849",UtilMap.getString(receipt,"FComment"));//备注

            double sl = 0.0;
            double zl = 0.0;
            if ("Pcs".equals(jjdw)) {
                sl = jjsl;
                if ("Kg".equals(xsdw)) {
                    zl = kcsl;
                }
            }else {
                zl = jjsl;
                if ("Pcs".equals(kcdw)) {
                    sl = kcsl;
                }
            }

            entryMap.put("Number1762915279108", sl);//数量
            entryMap.put("Number1762915289424", zl);//重量
            entryMap.put("rowStatus","Added");

            entry.add(entryMap);

            data.put("Sheet1760602277185",entry);

            dataList.add(data);
        }

        //处理同一收款单多个明细
        List<Map<String, Object>> list = mergeListMap(dataList, "ShortText1760602123650", "Sheet1760602277185");

        for (Map<String, Object> map : list) {
            String schemaCode = "YSD";
            //查询是否存在
            Map result2 = cpClient.getCpBoList(schemaCode, UtilMap.map("queryFilterType, propertyCode, propertyValue", "Eq", "ShortText1760602123650", UtilMap.getString(map, "ShortText1760602123650")),null, 0, 1, null);

            Map bizObjectPage = UtilMap.getMap(UtilMap.getMap(result2, "data"),"bizObjectPage");

            int totalElements = UtilMap.getInt(bizObjectPage, "totalElements");

            List<Map> items = (List<Map>) map.get("Sheet1760602277185");
            if (totalElements > 0) {
                //云枢更新应收单
                Map content = ((List<Map>) UtilMap.getList(bizObjectPage, "content")).get(0);

                Map map1 = UtilMap.getMap(content, "data");
                List<Map> list1 = UtilMap.getList(map1, "Sheet1760602277185");

                //原子表删除  覆盖更新
                for (Map map2 : list1) {
                    String id = UtilMap.getString(map2, "id");
                    items.add(UtilMap.map("id, rowStatus", id,"Deleted"));
                }

                String bizObjectId = UtilMap.getString(content,"bizObjectId");//主表实例id

                map.put("id",bizObjectId);

                Map result3 = cpClient.updateCpBo(schemaCode, map,null);
            }else {
                //云枢新增应收单
                items.forEach(item -> item.put("rowStatus", "added"));
                Map result3 = cpClient.createCpBo(schemaCode, map,null);
            }
        }
    }

    @Override
    public void syncSaleReturn() {
        log.info("开始同步销售退货单数据");
        K3CloudApi client = new K3CloudApi(initIden());

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

        int startRow = 0;
        int limit = 2000;

        BillQuery billQuery = new BillQuery();
        billQuery.setFormId("SAL_RETURNSTOCK");
        billQuery.setFieldKeys("FBillTypeID.FName,FBillNo,FDate,FRetcustId.FName,FSettleCurrId.FName,FHeadNote,FEntity_FEntryID,FMaterialId.FNumber,FMaterialId.FName,FMaterialId.FSpecification,FMaterialId.F_Sl_xingnengid,FMustqty,FRealQty,FPriceUnitId.FName,FPriceUnitQty,FPrice,FTaxPrice,FIsFree,FEntryTaxRate,FAmount,FEntryTaxAmount,FAllAmount,FReturnType.FDataValue,FStockId.FName,FDeliveryDate,FNote,FLot.FName");
        List<Map> filterString = new ArrayList<>();

        //审核日期为昨天至今天
        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FApproveDate","265",1,"","","0"));//审核日期在今天之前N天以后
//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FAPPROVEDATE","420","2025-10-21 00:00:00","","","0"));//审核日期年=XX
//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FDATE","420","2025-10-21 00:00:00","","","0"));//业务日期年=XX

        billQuery.setFilterString(filterString);
        billQuery.setLimit(limit);

        do {
            billQuery.setStartRow(startRow);
            String s = null;

            try {
                s = client.billQuery(JSONObject.toJSONString(billQuery));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            result = (List<Map>)JSONObject.parse(s);
            saleReturnList.addAll(result);

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


        List<Map<String,Object>> dataList = new ArrayList<>();

        for (Map receipt : saleReturnList) {
            Map data = new HashMap();

            data.put("ShortText1761032880442",UtilMap.getString(receipt,"FBillNo"));//单据编号
            data.put("ShortText1761032890399",UtilMap.getString(receipt,"FBillTypeID.FName"));//单据类型
            data.put("Date1761032895713",UtilMap.getString(receipt, "FDate").replace("T"," "));//日期
            data.put("ShortText1761032899575",UtilMap.getString(receipt,"FRetcustId.FName"));//退货客户
            data.put("ShortText1761032904895",UtilMap.getString(receipt,"FSettleCurrId.FName"));//结算币别
            data.put("ShortText1761032937812",UtilMap.getString(receipt,"FHeadNote"));//退货备注

            List<Map> entry = new ArrayList<>();
            Map entryMap = new HashMap();
            entryMap.put("ShortText1761033279692",UtilMap.getString(receipt,"FEntity_FEntryID"));//分录ID
            entryMap.put("ShortText1761032968041",UtilMap.getString(receipt,"FMaterialId.FNumber"));//物料编码
            entryMap.put("Text1761032973000",UtilMap.getString(receipt,"FMaterialId.FName"));//物料名称
            entryMap.put("ShortText1761033477673",UtilMap.getString(receipt,"FMaterialId.F_Sl_xingnengid"));//性能
            entryMap.put("ShortText1761032979494",UtilMap.getString(receipt,"FMaterialId.FSpecification"));//规格型号
            entryMap.put("Number1761032987168",UtilMap.getDouble(receipt,"FMustqty"));//应退数量
            entryMap.put("Number1761032997394",UtilMap.getDouble(receipt,"FRealQty"));//实退数量
            entryMap.put("ShortText1761033008702",UtilMap.getString(receipt,"FPriceUnitId.FName"));//计价单位
            entryMap.put("Number1761033960104",UtilMap.getDouble(receipt,"FPriceUnitQty"));//计价数量
            entryMap.put("Number1761033026518",UtilMap.getDouble(receipt,"FTaxPrice"));//含税单价
            entryMap.put("Number1761033015285",UtilMap.getDouble(receipt,"FPrice"));//单价
            entryMap.put("Number1761033046672",UtilMap.getDouble(receipt,"FEntryTaxRate"));//税率
            entryMap.put("Number1761033064064",UtilMap.getDouble(receipt,"FAmount"));//金额
            entryMap.put("Number1761033076151",UtilMap.getDouble(receipt,"FEntryTaxAmount"));//税额
            entryMap.put("Number1761033079296",UtilMap.getDouble(receipt,"FAllAmount"));//价税合计
            entryMap.put("Logic1761033036005",UtilMap.getBoolean(receipt,"FIsFree"));//是否赠品
            entryMap.put("ShortText1761033090318",UtilMap.getString(receipt,"FReturnType.FDataValue"));//退货类型
            entryMap.put("ShortText1761033099990",UtilMap.getString(receipt,"FStockId.FName"));//仓库
            entryMap.put("Date1761033104411",UtilMap.getString(receipt,"FDeliveryDate").replace("T"," "));//退货日期
            entryMap.put("Text1761033119394",UtilMap.getString(receipt,"FLot.FName"));//批号
            entryMap.put("ShortText1761033111040",UtilMap.getString(receipt,"FNote"));//备注
            entryMap.put("rowStatus","Added");

            entry.add(entryMap);

            data.put("Sheet1761032958852",entry);

            dataList.add(data);
        }

        //处理同一收款单多个明细
        List<Map<String, Object>> list = mergeListMap(dataList, "ShortText1761032880442", "Sheet1761032958852");

        for (Map<String, Object> map : list) {
            String schemaCode = "XSTHD";
            //查询是否存在
            Map result2 = cpClient.getCpBoList(schemaCode, UtilMap.map("queryFilterType, propertyCode, propertyValue", "Eq", "ShortText1761032880442", UtilMap.getString(map, "ShortText1761032880442")),null, 0, 1, null);

            Map bizObjectPage = UtilMap.getMap(UtilMap.getMap(result2, "data"),"bizObjectPage");

            int totalElements = UtilMap.getInt(bizObjectPage, "totalElements");

            List<Map> items = (List<Map>) map.get("Sheet1761032958852");
            if (totalElements > 0) {
                //云枢更新销售出库单
                Map content = ((List<Map>) UtilMap.getList(bizObjectPage, "content")).get(0);

                Map map1 = UtilMap.getMap(content, "data");
                List<Map> list1 = UtilMap.getList(map1, "Sheet1761032958852");

                //原子表删除  覆盖更新
                for (Map map2 : list1) {
                    String id = UtilMap.getString(map2, "id");
                    items.add(UtilMap.map("id, rowStatus", id,"Deleted"));
                }

                String bizObjectId = UtilMap.getString(content,"bizObjectId");//主表实例id

                map.put("id",bizObjectId);

                Map result3 = cpClient.updateCpBo(schemaCode, map,null);
            }else {
                //云枢新增销售出库单
                items.forEach(item -> item.put("rowStatus", "added"));
                Map result3 = cpClient.createCpBo(schemaCode, map,null);
            }
        }
    }

    @Override
    public void syncXingneng() {
        log.info("开始同步性能数据");
        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("Sl_xingneng");
        billQuery.setFieldKeys("FNumber,FName,Fmiduqty");
        List<Map> filterString = new ArrayList<>();

        //修改日期为昨天至今天 数据状态等于已审核
        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FModifyDate","265",1,"","","0"));//修改日期在今天之前N天以后
        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FDocumentStatus","105","C","","","0"));//数据状态等于XX

        billQuery.setFilterString(filterString);
        billQuery.setLimit(limit);

        do {
            billQuery.setStartRow(startRow);
            String s = null;

            try {
                s = client.billQuery(JSONObject.toJSONString(billQuery));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            result = (List<Map>)JSONObject.parse(s);
            materialList.addAll(result);

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

        for (Map map : materialList) {
            Map data = new HashMap();
            data.put("ShortText1763692732585",UtilMap.getString(map,"FName"));//名称
            data.put("ShortText1763692732107",UtilMap.getString(map,"FNumber"));//性能
            data.put("Number1763692741479",UtilMap.getDouble(map,"Fmiduqty"));//性能

            String schemaCode = "XN";

            //查询是否存在
            Map result2 = cpClient.getCpBoList(schemaCode, UtilMap.map("queryFilterType, propertyCode, propertyValue", "Eq", "ShortText1763692732107", UtilMap.getString(map,"FNumber")),null, 0, 1, null);

            Map bizObjectPage = UtilMap.getMap(UtilMap.getMap(result2, "data"),"bizObjectPage");

            int totalElements = UtilMap.getInt(bizObjectPage, "totalElements");

            if (totalElements > 0) {
                //云枢更新性能
                Map content = ((List<Map>) UtilMap.getList(bizObjectPage, "content")).get(0);

                String bizObjectId = UtilMap.getString(content,"bizObjectId");//主表实例id

                data.put("id",bizObjectId);

                Map result3 = cpClient.updateCpBo(schemaCode, data,null);
            }else {
                //云枢新增性能
                Map result3 = cpClient.createCpBo(schemaCode, data,null);
            }
        }
    }

    @Override
    public void syncSaleOrder() {
        log.info("开始同步销售订单数据");
        K3CloudApi client = new K3CloudApi(initIden());

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

        int startRow = 0;
        int limit = 2000;

        BillQuery billQuery = new BillQuery();
        billQuery.setFormId("SAL_SaleOrder");
        billQuery.setFieldKeys("FBillNo,FBillTypeID.FName,FDocumentStatus,FSaleDeptId.FName,FBusinessType,FCustId.FName,FCustId.FNumber,FSalerId.FName,F_WGR_Combo_re5,FDate,F_Sl_gendanyuan.FName,FNote,FSettleCurrId.FName,FRecConditionId.FName,FSettleModeId.FName,FBillTaxAmount,FBillAmount,FBillAllAmount,FBillAllAmount_LC,FIsIncludedTax,FIsPriceExcludeTax,FMaterialId.FNumber,FMaterialId.FName,FMaterialId.FSpecification,FMaterialId.F_Sl_xingnengid,FUnitID.FName,FQty,FPriceUnitId.FName,FPriceUnitQty,FPrice,FTaxPrice,FStockOutQty,FIsFree,FEntryTaxRate,FEntryTaxAmount,FAmount,FAllAmount,FAllAmount_LC,FDeliveryDate,FEntryNote,FMinPlanDeliveryDate,F_VMKV_MPPRICE,F_VMKV_SCCQ1,F_WGR_Combo_qtr");
        List<Map> filterString = new ArrayList<>();

        //审核日期为昨天至今天
        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FApproveDate","265",1,"","","0"));//审核日期在今天之前N天以后
//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FBillNo","67","S301-260513014","","","0"));//单据编号等于XX

        billQuery.setFilterString(filterString);
        billQuery.setLimit(limit);

        do {
            billQuery.setStartRow(startRow);
            String s = null;

            try {
                s = client.billQuery(JSONObject.toJSONString(billQuery));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            result = (List<Map>)JSONObject.parse(s);
            saleOrderList.addAll(result);

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


        List<Map<String,Object>> dataList = new ArrayList<>();

        Map<String,String> cpCustomerMap = new HashMap<>();
        Map<String,Map> cpUserMap = new HashMap<>();

        for (Map saleOut : saleOrderList) {
            Map data = new HashMap();

            data.put("ShortText1775629055296",UtilMap.getString(saleOut,"FBillNo"));//单据编号
            data.put("Dropdown1775628963571",UtilMap.getString(saleOut,"FBillTypeID.FName"));//单据类型
            String fDocumentStatus = UtilMap.getString(saleOut, "FDocumentStatus");
            String fDocumentStatusValue = "";
            switch (fDocumentStatus){
                case "A": fDocumentStatusValue = "创建";break;
                case "B": fDocumentStatusValue = "审核中";break;
                case "C": fDocumentStatusValue = "已审核";break;
                case "D": fDocumentStatusValue = "重新审核";break;
                case "Z": fDocumentStatusValue = "暂存";break;
                default: break;
            }
            data.put("Dropdown1775629499775",fDocumentStatusValue);//单据状态
            data.put("ShortText1775629254048",UtilMap.getString(saleOut,"FSaleDeptId.FName"));//销售部门
            String fBusinessType = UtilMap.getString(saleOut, "FBusinessType");
            String fBusinessTypeValue = "";
            switch (fBusinessType){
                case "NORMAL": fBusinessTypeValue = "普通销售";break;
                case "CONSIGNMENT": fBusinessTypeValue = "寄售";break;
                case "STRAIGHT": fBusinessTypeValue = "直运销售";break;
                case "DRPTRANS": fBusinessTypeValue = "分销调拨";break;
                case "DRPSALE": fBusinessTypeValue = "分销购销";break;
                case "VMI": fBusinessTypeValue = "VMI业务";break;
                case "RETURNSO": fBusinessTypeValue = "退货订单";break;
                default:break;
            }
            data.put("Dropdown1775629396327",fBusinessTypeValue);//业务类型
//            data.put("",UtilMap.getString(saleOut,""));//客户
            data.put("ShortText1775637878744",UtilMap.getString(saleOut,"FCustId.FName"));//客户名称
            data.put("Text1775637885319",UtilMap.getString(saleOut,"FCustId.FNumber"));//客户编号
            data.put("ShortText1776926946903",UtilMap.getString(saleOut, "FSalerId.FName"));//销售员
            String fWgrComboRe5 = UtilMap.getString(saleOut, "F_WGR_Combo_re5");
            String fWgrComboRe5Value = "";
            switch (fWgrComboRe5){
                case "YQ001": fWgrComboRe5Value = "S";break;
                case "YQ002": fWgrComboRe5Value = "A";break;
                case "YQ003": fWgrComboRe5Value = "B";break;
                default:break;
            }
            data.put("Dropdown1775629436727",fWgrComboRe5Value);//订单要求
            data.put("Date1775629061650",UtilMap.getString(saleOut, "FDate").split("\\.")[0].replace("T"," "));//日期
            data.put("ShortText1776926951569",UtilMap.getString(saleOut, "F_Sl_gendanyuan.FName"));//跟单员



            data.put("LongText1775629459686",UtilMap.getString(saleOut,"FNote"));//备注
            data.put("ShortText1775629336527",UtilMap.getString(saleOut,"FSettleCurrId.FName"));//结算币别
            data.put("Number1775629642435",UtilMap.getDouble(saleOut,"FBillTaxAmount"));//税额
            data.put("Dropdown1775629423209",UtilMap.getString(saleOut,"FRecConditionId.FName"));//收款条件
            data.put("Number1775629663162",UtilMap.getDouble(saleOut,"FBillAmount"));//金额
            data.put("Dropdown1775629587135",UtilMap.getString(saleOut,"FSettleModeId.FName"));//结算方式
            data.put("Number1775629668267",UtilMap.getDouble(saleOut,"FBillAllAmount"));//价税合计
            data.put("Number1779948938421",UtilMap.getDouble(saleOut,"FBillAllAmount_LC"));//价税合计（本位币）
            data.put("Logic1775629684705",UtilMap.getBoolean(saleOut,"FIsIncludedTax"));//是否含税
            data.put("Logic1775629696188",UtilMap.getString(saleOut,"FIsPriceExcludeTax"));//价外税



            List<Map> entry = new ArrayList<>();
            Map entryMap = new HashMap();
            entryMap.put("ShortText1775629887424",UtilMap.getString(saleOut,"FMaterialId.FNumber"));//物料编码
            entryMap.put("ShortText1775629901235",UtilMap.getString(saleOut,"FMaterialId.FName"));//物料名称
            entryMap.put("Text1775629907213",UtilMap.getString(saleOut,"FMaterialId.FSpecification"));//规格型号
            entryMap.put("Text1775630134129",UtilMap.getString(saleOut,"FMaterialId.F_Sl_xingnengid"));//性能
            entryMap.put("Text1775629912179",UtilMap.getString(saleOut,"FUnitID.FName"));//销售单位
            entryMap.put("Number1775629957043",UtilMap.getDouble(saleOut,"FQty"));//销售数量
            entryMap.put("Number1785223383466",UtilMap.getDouble(saleOut,"FStockOutQty"));//已出库数量
            entryMap.put("Number1785223387106",(UtilMap.getDouble(saleOut,"FQty")-UtilMap.getDouble(saleOut,"FStockOutQty")));//未出库数量=销售数量-已出库数量
            entryMap.put("Text1775629930913",UtilMap.getString(saleOut,"FPriceUnitId.FName"));//计价单位
            entryMap.put("Number1775629983997",UtilMap.getDouble(saleOut,"FPriceUnitQty"));//计价数量
            entryMap.put("Number1775629999628",UtilMap.getDouble(saleOut,"FPrice"));//单价
            entryMap.put("Number1775630010204",UtilMap.getDouble(saleOut,"FTaxPrice"));//含税单价
            entryMap.put("Logic1775630018437",UtilMap.getBoolean(saleOut,"FIsFree"));//是否赠品
            entryMap.put("Number1775630028537",UtilMap.getDouble(saleOut,"FEntryTaxRate"));//税率
            entryMap.put("Number1775630058476",UtilMap.getDouble(saleOut,"FEntryTaxAmount"));//税额
            entryMap.put("Number1775630070637",UtilMap.getDouble(saleOut,"FAmount"));//金额
            entryMap.put("Number1775630077547",UtilMap.getDouble(saleOut,"FAllAmount"));//价税合计
            entryMap.put("Number1779949465109",UtilMap.getDouble(saleOut,"FAllAmount_LC"));//价税合计（本位币）
            entryMap.put("Date1775630094759",UtilMap.getString(saleOut,"FDeliveryDate").split("\\.")[0].replace("T"," "));//客户交期
            entryMap.put("LongText1775630108001",UtilMap.getString(saleOut,"FEntrynote"));//备注
            entryMap.put("Date1775630116970",UtilMap.getString(saleOut,"FMinPlanDeliveryDate").split("\\.")[0].replace("T"," "));//计划交货日期
            entryMap.put("Number1775630183877",UtilMap.getDouble(saleOut,"F_VMKV_MPPRICE"));//报价价格
            String fVmkvSccq1 = UtilMap.getString(saleOut, "F_VMKV_SCCQ1");
            String fVmkvSccq1Value = "";
            switch (fVmkvSccq1){
                case "ART": fVmkvSccq1Value = "佳丰";break;
                case "JLCC": fVmkvSccq1Value = "金轮";break;
                case "NOT": fVmkvSccq1Value = "暂不确定";break;
                default:break;
            }
            entryMap.put("ShortText1775630203699",fVmkvSccq1Value);//生产厂区
            entryMap.put("ShortText1775630212729",UtilMap.getString(saleOut,"F_WGR_Combo_qtr"));//产品质量等级
            entryMap.put("rowStatus","Added");

            entry.add(entryMap);

            data.put("Sheet1775629877034",entry);

            dataList.add(data);
        }

        //处理同一出库单多个明细
        List<Map<String, Object>> list = mergeListMap(dataList, "ShortText1775629055296", "Sheet1775629877034");

        List<Map> cpDepartmentInfo = cpClient.getCpDepartmentInfo();
        Map<String, String> cpDepartmentMap = new HashMap<>();
        for (Map cpDepartment : cpDepartmentInfo) {
            cpDepartmentMap.put(UtilMap.getString(cpDepartment,"id"),UtilMap.getString(cpDepartment,"name"));
        }

        //处理特殊字段格式
        for (Map<String, Object> stringObjectMap : list) {
            //成员
            String salerName = UtilMap.getString(stringObjectMap,"ShortText1776926946903");
            if(cpUserMap.containsKey(salerName)){
                Map cpUserInfo = cpUserMap.get(salerName);
                stringObjectMap.put("StaffSingle1775629353797",cpUserInfo);//销售员
                stringObjectMap.put("ShortText1775629254048",cpDepartmentMap.get(UtilMap.getString(cpUserInfo,"mainDepartmentId")));//销售部门
            }else {
                List<Map> cpUserInfoList = cpClient.getCpUserInfo(null, null, null, null, salerName, 0, 10);
                if (cpUserInfoList.size() == 1){
                    Map cpUserInfo = (Map) cpUserInfoList.get(0);
                    cpUserInfo.put("type",3);
                    stringObjectMap.put("StaffSingle1775629353797",cpUserInfo);//销售员
                    cpUserMap.put(salerName,cpUserInfo);

                    stringObjectMap.put("ShortText1775629254048",cpDepartmentMap.get(UtilMap.getString(cpUserInfo,"mainDepartmentId")));//销售部门
                }else if (cpUserInfoList.size() > 1){
                    Map cpUserInfo = (Map) cpUserInfoList.get(cpUserInfoList.size()-1);
                    cpUserInfo.put("type",3);
                    stringObjectMap.put("StaffSingle1775629353797",cpUserInfo);//销售员
                    cpUserMap.put(salerName,cpUserInfo);

                    stringObjectMap.put("ShortText1775629254048",cpDepartmentMap.get(UtilMap.getString(cpUserInfo,"mainDepartmentId")));//销售部门
                }else {
                    stringObjectMap.put("StaffSingle1775629353797",null);
                }
            }

            String gendanName = UtilMap.getString(stringObjectMap, "ShortText1776926951569");
            if(cpUserMap.containsKey(gendanName)){
                Map cpUserInfo = new HashMap(cpUserMap.get(gendanName));
                stringObjectMap.put("StaffSelector1775629377100",cpUserInfo);//跟单员
            }else {
                List<Map> cpUserInfoList = cpClient.getCpUserInfo(null, null, null, null, gendanName, 0, 10);
                if (cpUserInfoList.size() == 1){
                    Map cpUserInfo = (Map) cpUserInfoList.get(0);
                    cpUserInfo.put("type",3);
                    stringObjectMap.put("StaffSelector1775629377100",cpUserInfo);//跟单员
                    cpUserMap.put(gendanName,cpUserInfo);
                }else if (cpUserInfoList.size() > 1){
                    Map cpUserInfo = (Map) cpUserInfoList.get(cpUserInfoList.size()-1);
                    cpUserInfo.put("type",3);
                    stringObjectMap.put("StaffSelector1775629377100",cpUserInfo);//跟单员
                    cpUserMap.put(gendanName,cpUserInfo);
                }else {
                    stringObjectMap.put("StaffSelector1775629377100",null);
                }
            }

            //关联表单
            String customerCode = UtilMap.getString(stringObjectMap,"Text1775637885319");
            if (cpCustomerMap.containsKey(customerCode)){
                stringObjectMap.put("RelevanceForm1775629076865",cpCustomerMap.get(customerCode));//客户
            }else {
                Map cpBoList = cpClient.getCpBoList("KHDA", UtilMap.map("queryFilterType, propertyCode, propertyValue", "Eq", "ShortText1758195840127", customerCode), null, 0, 1, null);
                Map bizObjectPage = UtilMap.getMap(UtilMap.getMap(cpBoList, "data"),"bizObjectPage");
                int totalElements = UtilMap.getInt(bizObjectPage, "totalElements");
                if (totalElements == 1){
                    Map content = ((List<Map>) UtilMap.getList(bizObjectPage, "content")).get(0);

                    String bizObjectId = UtilMap.getString(content, "bizObjectId");

                    stringObjectMap.put("RelevanceForm1775629076865",bizObjectId);//客户

                    cpCustomerMap.put(customerCode,bizObjectId);
                }
            }
        }

        System.out.println("111");

        for (Map<String, Object> map : list) {
            String schemaCode = "XSDD_JDTB";
            //查询是否存在
            Map result2 = cpClient.getCpBoList(schemaCode, UtilMap.map("queryFilterType, propertyCode, propertyValue", "Eq", "ShortText1775629055296", UtilMap.getString(map, "ShortText1775629055296")),null, 0, 1, null);

            Map bizObjectPage = UtilMap.getMap(UtilMap.getMap(result2, "data"),"bizObjectPage");

            int totalElements = UtilMap.getInt(bizObjectPage, "totalElements");

            List<Map> items = (List<Map>) map.get("Sheet1775629877034");
            if (totalElements > 0) {
                //云枢更新销售订单
                Map content = ((List<Map>) UtilMap.getList(bizObjectPage, "content")).get(0);

                Map map1 = UtilMap.getMap(content, "data");
                List<Map> list1 = UtilMap.getList(map1, "Sheet1775629877034");

                //原子表删除  覆盖更新
                for (Map map2 : list1) {
                    String id = UtilMap.getString(map2, "id");
                    items.add(UtilMap.map("id, rowStatus", id,"Deleted"));
                }

                String bizObjectId = UtilMap.getString(content,"bizObjectId");//主表实例id

                map.put("id",bizObjectId);

                Map result3 = cpClient.updateCpBo(schemaCode, map,null);
            }else {
                //云枢新增销售出库单
                items.forEach(item -> item.put("rowStatus", "added"));
                Map result3 = cpClient.createCpBo(schemaCode, map,null);
            }
        }
    }

    @Override
    public void syncReceiptVerification() {
        log.info("开始同步应收收款核销明细");
        K3CloudApi client = new K3CloudApi(initIden());

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

        int startRow = 0;
        int limit = 2000;

        BillQuery billQuery = new BillQuery();
        billQuery.setFormId("AR_MatchRecord");
        billQuery.setFieldKeys("FBILLNO,FPLANAMOUNTFOR,FPLANAMOUNT,FCURWRITTENOFFAMOUNTFOR,FCURWRITTENOFFAMOUNT,FCURRENCYID.FName,FSOURCETYPE.FName,FSRCBILLNO,FVERIFYDATE,FCONTACTUNITTYPE,FCONTACTUNIT.FNumber,FCONTACTUNIT.FName,FBILLNUMBER");
        List<Map> filterString = new ArrayList<>();

        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FVERIFYDATE","265",1,"","","0"));//核销日期在今天之前N天以后
//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FVERIFYDATE","39","2026-03-30 00:00:00","","","0"));//核销日期>=XX
//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FVERIFYDATE","16","2026-03-31 00:00:00","","","0"));//核销日期<=XX
        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FCURWRITTENOFFAMOUNTFOR","21",0,"","","0"));//本次核销金额>0
        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FSOURCETYPE.FName","17","标准应收单","","","0"));//单据类型等于XX
//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FCONTACTUNIT.FName","17","安徽名创磁业有限公司","","","0"));//往来单位名称包含XX
//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FVERIFYSEQ","76",158051,"","","0"));//核销序号等于XX
//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FSRCBILLNO","17","AR00082020","","","0"));//应收单号等于XX

        billQuery.setFilterString(filterString);
        billQuery.setLimit(limit);

        do {
            billQuery.setStartRow(startRow);
            String s = null;

            try {
                s = client.billQuery(JSONObject.toJSONString(billQuery));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            result = (List<Map>)JSONObject.parse(s);
            list.addAll(result);

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

        System.out.println("1111");

        for (Map map : list) {
            Map body = new HashMap();
            body.put("ShortText1776845631494",UtilMap.getString(map, "FBILLNO"));//核销单号
            Double fplanamountfor = UtilMap.getDouble(map, "FPLANAMOUNTFOR");
            body.put("Number1778657486463", fplanamountfor);//应收金额
            body.put("Number1778657494744",UtilMap.getDouble(map, "FPLANAMOUNT"));//应收金额本位币
            body.put("Number1776845666515",UtilMap.getDouble(map, "FCURWRITTENOFFAMOUNTFOR"));//本次核销金额
            body.put("Number1776845698524",UtilMap.getDouble(map, "FCURWRITTENOFFAMOUNT"));//本次核销金额本位币
            body.put("ShortText1776845718075",UtilMap.getString(map, "FCURRENCYID.FName"));//结算币别
            body.put("ShortText1776845730884",UtilMap.getString(map, "FSOURCETYPE.FName"));//单据类型
            String fsrcbillno = UtilMap.getString(map, "FSRCBILLNO");
            body.put("ShortText1776845842726", fsrcbillno);//应收单编号
            body.put("Date1776845858285",UtilMap.getString(map, "FVERIFYDATE").split("\\.")[0].replace("T"," "));//核销日期
            String fcontactunittype = UtilMap.getString(map, "FCONTACTUNITTYPE");
            String fcontactunittypeValue = "";
            switch (fcontactunittype){
                case "BD_Supplier":fcontactunittypeValue="供应商";break;
                case "BD_Customer":fcontactunittypeValue="客户";break;
                case "BD_Empinfo":fcontactunittypeValue="员工";break;
                case "FIN_OTHERS":fcontactunittypeValue="其他往来单位";break;
                default:break;
            }
            body.put("ShortText1776845885255",fcontactunittypeValue);//往来单位类型
            body.put("ShortText1776845907662",UtilMap.getString(map, "FCONTACTUNIT.FNumber"));//往来单位编码
            body.put("Text1776845928307",UtilMap.getString(map, "FCONTACTUNIT.FName"));//往来单位名称

//            String saleOrderNumber = UtilMap.getString(map, "FBILLNUMBER");//销售订单号
            String saleOrderNumber = "";//销售订单号    必须查询应收单获取到期日

            if (Strings.isBlank(saleOrderNumber)){
                //查询应收单
                BillQuery billQuery2 = new BillQuery();
                billQuery2.setFormId("AR_receivable");
                billQuery2.setFieldKeys("FBillNo,FSourceBillNo,FENDDATE");
                List<Map> filterString2 = new ArrayList<>();
                filterString2.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FBillNo","67",fsrcbillno,"","","0"));//单据编号等于XX
                filterString2.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FPAYAMOUNTFOR","76",fplanamountfor,"","","0"));//收款计划-应收金额等于XX
                billQuery2.setFilterString(filterString2);
                billQuery2.setLimit(1);
                billQuery2.setStartRow(0);

                try {
                    List<Map> ysdList = (List<Map>) JSONObject.parse(client.billQuery(JSONObject.toJSONString(billQuery2)));
                    if (!ysdList.isEmpty()){
                        Map ysd = ysdList.get(0);
                        String fSourceBillNo = UtilMap.getString(ysd, "FSourceBillNo");//销售出库单单号
                        String fenddate = UtilMap.getString(ysd, "FENDDATE").split("\\.")[0].replace("T"," ");//到期日
                        body.put("Date1778657519700",fenddate);

                        if (Strings.isNotBlank(fSourceBillNo)){
                            //查询销售出库单
                            BillQuery billQuery3 = new BillQuery();
                            billQuery3.setFormId("SAL_OUTSTOCK");
                            billQuery3.setFieldKeys("FBillNo,FSrcBillNo");
                            List<Map> filterString3 = new ArrayList<>();
                            filterString3.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FBillNo","17",fSourceBillNo,"","","0"));//单据编号包含XX
                            billQuery3.setFilterString(filterString3);
                            billQuery3.setLimit(1);
                            billQuery3.setStartRow(0);

                            List<Map> ckdList = (List<Map>) JSONObject.parse(client.billQuery(JSONObject.toJSONString(billQuery3)));
                            if (!ckdList.isEmpty()){
                                Map ckd = ckdList.get(0);

                                saleOrderNumber = UtilMap.getString(ckd, "FSrcBillNo");//销售订单号
                            }
                        }
                    }
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
            body.put("ShortText1776845949665",saleOrderNumber);

            String schemaCode = "YSSKHXJL";

            //查询是否存在
            Map queryCondition = new HashMap();
            queryCondition.put("op", "and");
            queryCondition.put("items", Arrays.asList(
                    UtilMap.map("queryFilterType, propertyCode, propertyValue", "Eq", "ShortText1776845631494", UtilMap.getString(body, "ShortText1776845631494")),
                    UtilMap.map("queryFilterType, propertyCode, propertyValue", "Eq", "ShortText1776845842726", UtilMap.getString(body, "ShortText1776845842726"))));
            Map result2 = cpClient.getCpBoList(schemaCode,queryCondition,null, 0, 1, null);

            Map bizObjectPage = UtilMap.getMap(UtilMap.getMap(result2, "data"),"bizObjectPage");

            int totalElements = UtilMap.getInt(bizObjectPage, "totalElements");

            if (totalElements > 0) {
                //更新
                Map content = ((List<Map>) UtilMap.getList(bizObjectPage, "content")).get(0);

                String bizObjectId = UtilMap.getString(content,"bizObjectId");//主表实例id

                body.put("id",bizObjectId);

                Map result3 = cpClient.updateCpBo(schemaCode, body,null);
            }else {
                //云枢新增销售出库单
                Map result3 = cpClient.createCpBo(schemaCode, body,null);
            }

            //核销后更新应收单已核销金额，累加
        }



    }

    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;
    }

    public static List<Map<String, Object>> mergeListMap(List<Map<String, Object>> originalList,String key,String list) {
        // 使用 Map 来临时存储合并后的结果，key 为 code，value 为合并后的 Map
        Map<String, Map<String, Object>> mergedMap = new HashMap<>();

        for (Map<String, Object> item : originalList) {
            String code = (String) item.get(key);
            @SuppressWarnings("unchecked")
            List<Map<String, Object>> details = (List<Map<String, Object>>) item.get(list);

            if (mergedMap.containsKey(code)) {
                // 如果已存在该 code，只合并 details
                Map<String, Object> existingItem = mergedMap.get(code);
                @SuppressWarnings("unchecked")
                List<Map<String, Object>> existingDetails = (List<Map<String, Object>>) existingItem.get(list);
                existingDetails.addAll(details);
            } else {
                // 如果不存在该 key，保存整个 Map（包括其他 key）
                // 但需要深拷贝 list，避免后续修改影响原始数据
                Map<String, Object> newItem = new HashMap<>();
                for (Map.Entry<String, Object> entry : item.entrySet()) {
                    if ("details".equals(entry.getKey())) {
                        // 深拷贝 details 列表
                        @SuppressWarnings("unchecked")
                        List<Map<String, Object>> originalDetails = (List<Map<String, Object>>) entry.getValue();
                        newItem.put(entry.getKey(), new ArrayList<>(originalDetails));
                    } else {
                        newItem.put(entry.getKey(), entry.getValue());
                    }
                }
                mergedMap.put(code, newItem);
            }
        }

        // 转换回 List
        return new ArrayList<>(mergedMap.values());
    }


}
