Ver código fonte

Merge remote-tracking branch 'origin/master'

lfx 6 dias atrás
pai
commit
164aaee2ef

+ 1 - 1
mjava-huagao/src/test/java/com/malk/huagao/EqbTest.java

@@ -132,7 +132,7 @@ public class EqbTest {
 //            reqBodyObj.put("convertToPDF", "true");
             reqBodyObj.put("convertToHTML", true);
             reqBodyObj.put("fileName", "其他客户销售合同.docx");
-            reqBodyObj.put("fileSize", "28246 ");
+            reqBodyObj.put("fileSize", "28246");
             //reqBodyObj.put("convertToHTML", "false");
 
             // 请求Body体数据

+ 8 - 0
mjava-jinlun/src/main/java/com/malk/jinlun/schedule/JinlunTask.java

@@ -62,4 +62,12 @@ public class JinlunTask {
         jinlunTaskService.syncSaleOrder();
     }
 
+    //定时同步应收收款核销记录
+    @Scheduled(cron = "0 7 0 * * ?")
+    public void syncReceiptVerification(){
+        jinlunTaskService.syncReceiptVerification();
+    }
+
+
+
 }

+ 3 - 0
mjava-jinlun/src/main/java/com/malk/jinlun/service/JinlunTaskService.java

@@ -15,4 +15,7 @@ public interface JinlunTaskService {
 
     void syncSaleOrder();
 
+    //应收收款核销记录
+    void syncReceiptVerification();
+
 }

+ 153 - 14
mjava-jinlun/src/main/java/com/malk/jinlun/service/impl/JinlunTaskServiceImpl.java

@@ -9,13 +9,11 @@ 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.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 @Slf4j
 @Service
@@ -254,7 +252,7 @@ public class JinlunTaskServiceImpl implements JinlunTaskService {
                 Map map1 = UtilMap.getMap(content, "data");
                 List<Map> list1 = UtilMap.getList(map1, "Sheet1760153734916");
 
-                for (int i = 0; i < items.size(); i++) {
+                for (int i = 0; i < list1.size(); i++) {
                     items.get(i).put("rowStatus", "Modified");
                     items.get(i).put("id", (UtilMap.getString(list1.get(i),"id")));//子表实例id
                 }
@@ -393,7 +391,7 @@ public class JinlunTaskServiceImpl implements JinlunTaskService {
                 Map map1 = UtilMap.getMap(content, "data");
                 List<Map> list1 = UtilMap.getList(map1, "Sheet1760585205663");
 
-                for (int i = 0; i < items.size(); i++) {
+                for (int i = 0; i < list1.size(); i++) {
                     items.get(i).put("rowStatus", "Modified");
                     items.get(i).put("id", (UtilMap.getString(list1.get(i),"id")));//子表实例id
                 }
@@ -789,7 +787,7 @@ public class JinlunTaskServiceImpl implements JinlunTaskService {
 
         //审核日期为昨天至今天
         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","S304-260410001","","","0"));//单据编号等于XX
+//        filterString.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FBillNo","67","S305-251031001","","","0"));//单据编号等于XX
 
         billQuery.setFilterString(filterString);
         billQuery.setLimit(limit);
@@ -848,7 +846,7 @@ public class JinlunTaskServiceImpl implements JinlunTaskService {
 //            data.put("",UtilMap.getString(saleOut,""));//客户
             data.put("ShortText1775637878744",UtilMap.getString(saleOut,"FCustId.FName"));//客户名称
             data.put("Text1775637885319",UtilMap.getString(saleOut,"FCustId.FNumber"));//客户编号
-            data.put("StaffSingle1775629353797",UtilMap.getString(saleOut, "FSalerId.FName"));//销售员
+            data.put("ShortText1776926946903",UtilMap.getString(saleOut, "FSalerId.FName"));//销售员
             String fWgrComboRe5 = UtilMap.getString(saleOut, "F_WGR_Combo_re5");
             String fWgrComboRe5Value = "";
             switch (fWgrComboRe5){
@@ -859,7 +857,7 @@ public class JinlunTaskServiceImpl implements JinlunTaskService {
             }
             data.put("Dropdown1775629436727",fWgrComboRe5Value);//订单要求
             data.put("Date1775629061650",UtilMap.getString(saleOut, "FDate").split("\\.")[0].replace("T"," "));//日期
-            data.put("StaffSelector1775629377100",UtilMap.getString(saleOut, "F_Sl_gendanyuan.FName"));//跟单员
+            data.put("ShortText1776926951569",UtilMap.getString(saleOut, "F_Sl_gendanyuan.FName"));//跟单员
 
 
 
@@ -920,7 +918,7 @@ public class JinlunTaskServiceImpl implements JinlunTaskService {
         //处理特殊字段格式
         for (Map<String, Object> stringObjectMap : list) {
             //成员
-            String salerName = UtilMap.getString(stringObjectMap,"StaffSingle1775629353797");
+            String salerName = UtilMap.getString(stringObjectMap,"ShortText1776926946903");
             if(cpUserMap.containsKey(salerName)){
                 Map cpUserInfo = cpUserMap.get(salerName);
                 stringObjectMap.put("StaffSingle1775629353797",cpUserInfo);//销售员
@@ -936,10 +934,10 @@ public class JinlunTaskServiceImpl implements JinlunTaskService {
                 }
             }
 
-            String gendanName = UtilMap.getString(stringObjectMap, "StaffSelector1775629377100");
+            String gendanName = UtilMap.getString(stringObjectMap, "ShortText1776926951569");
             if(cpUserMap.containsKey(gendanName)){
-                Map cpUserInfo = cpUserMap.get(gendanName);
-                stringObjectMap.put("StaffSingle1775629353797",cpUserInfo);//跟单员
+                Map cpUserInfo = new HashMap(cpUserMap.get(gendanName));
+                stringObjectMap.put("StaffSelector1775629377100",cpUserInfo);//跟单员
             }else {
                 List<Map> cpUserInfoList = cpClient.getCpUserInfo(null, null, null, null, gendanName, 0, 1);
                 if (cpUserInfoList.size() == 1){
@@ -992,7 +990,7 @@ public class JinlunTaskServiceImpl implements JinlunTaskService {
                 List<Map> list1 = UtilMap.getList(map1, "Sheet1775629877034");
 
                 if (!list1.isEmpty()){
-                    for (int i = 0; i < items.size(); i++) {
+                    for (int i = 0; i < list1.size(); i++) {
                         items.get(i).put("rowStatus", "Modified");
                         items.get(i).put("id", (UtilMap.getString(list1.get(i),"id")));//子表实例id
                     }
@@ -1013,6 +1011,147 @@ public class JinlunTaskServiceImpl implements JinlunTaskService {
         }
     }
 
+    @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,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-01-01 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
+
+        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"));//核销单号
+            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");//销售订单号
+
+            if (Strings.isBlank(saleOrderNumber)){
+                //查询应收单
+                BillQuery billQuery2 = new BillQuery();
+                billQuery2.setFormId("AR_receivable");
+                billQuery2.setFieldKeys("FBillNo,FSourceBillNo");
+                List<Map> filterString2 = new ArrayList<>();
+                filterString2.add(UtilMap.map("FieldName, Compare, Value, Left, Right, Logic","FBillNo","17",fsrcbillno,"","","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");//销售出库单单号
+
+                        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介绍中的登录配置文件说明。

+ 5 - 0
mjava-jinlun/src/test/java/com/malk/jinlun/DdTest.java

@@ -76,6 +76,11 @@ public class DdTest {
         jinlunTaskService.syncSaleOrder();
     }
 
+    @Test
+    public void test17() {
+        jinlunTaskService.syncReceiptVerification();
+    }
+
     @Test
     public void test8() {
         try {

+ 23 - 7
mjava-siku/src/main/java/com/malk/siku/controller/SikuController.java

@@ -95,20 +95,30 @@ public class SikuController {
         return sikuService.checkBudgetAmt(map);
     }*/
 
-    //每刻云票收款核销回调
-    @PostMapping("/receive/callback")
+    //每刻云票收款核销回调
+    @PostMapping("/VERIFICATION_AR/callback")
     public McR callback(@RequestBody Map map){
-        log.info("每刻云票收款核销回调:{}", JSONObject.toJSONString(map));
+        log.info("每刻云票收款核销回调:{}", JSONObject.toJSONString(map));
 
         sikuService.invoiceWriteBack(map);
 
         return McR.success();
     }
 
-    //每刻云票开票回调
-    @PostMapping("/application/callback")
+    //每刻云票应收单回调(开票成功)
+    @PostMapping("/RECEIVABLE_AR/callback")
+    public McR callback9(@RequestBody Map map){
+        log.info("每刻云票应收单完成回调:{}",JSONObject.toJSONString(map));
+
+        sikuService.invoiceWriteBack9(map);
+
+        return McR.success();
+    }
+
+    //每刻云票开票申请单回调(开票失败)
+    @PostMapping("/INVOICE_APPLICATION_AR/callback")
     public McR callback2(@RequestBody Map map){
-        log.info("每刻云票开票回调:{}",JSONObject.toJSONString(map));
+        log.info("每刻云票开票申请单回调:{}",JSONObject.toJSONString(map));
 
         sikuService.invoiceWriteBack2(map);
 
@@ -167,7 +177,7 @@ public class SikuController {
 
     //每刻报销费用报销单完成回调(项目报销单(个人)、项目差旅报销单、打车(企业支付)("是否有项目"为【是】))
     @PostMapping("/reimbursement2/callback")
-    public McR callback8(@RequestBody Map map){
+        public McR callback8(@RequestBody Map map){
         log.info("每刻报销费用报销单完成回调:{}", JSONObject.toJSONString(map));
 
         sikuService.invoiceWriteBack8(map);
@@ -183,6 +193,12 @@ public class SikuController {
         return McR.success();
     }
 
+    //创建/更新企业滴滴项目
+    @PostMapping("/ddProject")
+    public McR ddProject(@RequestBody Map map){
+        return sikuService.ddProject(map);
+    }
+
     @GetMapping("/files/{fileId}")
     public ResponseEntity<Resource> getFileResource(
             @PathVariable String fileId,

+ 2 - 1
mjava-siku/src/main/java/com/malk/siku/schedule/SikuTask.java

@@ -21,7 +21,8 @@ public class SikuTask {
     private SikuTaskService sikuTaskService;
 
     //定时同步借款台账
-    @Scheduled(cron = "0 0 0 * * ?")
+    //早上9点至晚上6点 每小时同步一次
+    @Scheduled(cron = "0 0 9-18 * * ?")
     public void syncMaterial(){
         sikuTaskService.syncLoanManage();
     }

+ 4 - 0
mjava-siku/src/main/java/com/malk/siku/service/SikuService.java

@@ -36,4 +36,8 @@ public interface SikuService {
     void invoiceWriteBack8(Map map);
 
     McR saveRepayment(Map map);
+
+    void invoiceWriteBack9(Map map);
+
+    McR ddProject(Map map);
 }

+ 379 - 115
mjava-siku/src/main/java/com/malk/siku/service/impl/SikuServiceImpl.java

@@ -11,6 +11,7 @@ import com.malk.service.dingtalk.DDClient_Personnel;
 import com.malk.siku.service.SikuService;
 import com.malk.siku.utils.MkBxUtil;
 import com.malk.siku.utils.MkYpUtil;
+import com.malk.siku.utils.QyddUtil;
 import com.malk.utils.UtilHttp;
 import com.malk.utils.UtilMap;
 import lombok.extern.slf4j.Slf4j;
@@ -24,7 +25,9 @@ import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.net.HttpURLConnection;
 import java.net.URL;
+import java.text.SimpleDateFormat;
 import java.util.*;
+import java.util.stream.Collectors;
 
 @Slf4j
 @Service
@@ -41,6 +44,35 @@ public class SikuServiceImpl implements SikuService {
     @Autowired
     private DDClient ddClient;
 
+    //每刻报销 测试环境
+    /*private static String mkbx_empId = "18857526310";//默认 周漂
+    private static String mkbx_deptId = "DI205228744816739500";//默认 财务部*/
+
+    //每刻报销 正式环境
+    private static String mkbx_empId = "HZ769";//默认 周漂
+    private static String mkbx_deptId = "DI205228744816739500";//默认 财务部
+
+    //每刻云票 测试环境
+//    private static String mkyp_empId = "18857526310";//默认 周漂
+
+    //每刻云票 正式环境
+    private static String mkyp_empId = "HZ769";//默认 周漂
+
+    private static final Map<String,String> ddLegalEntity = new HashMap<>();//企业滴滴公司主体
+    static{
+        ddLegalEntity.put("91110105MA04B5ND7J","1125994677035472");//思库共创(北京)营销策划有限公司
+        ddLegalEntity.put("91330110MA2AYPX2X1","1125994676962964");//杭州光映场景科技有限公司
+        ddLegalEntity.put("91310120MA1JJJL131","1125994676938831");//上海造酷文化科技有限公司
+        ddLegalEntity.put("913301060793092966","1125994676742442");//杭州思库营销策划有限公司
+        ddLegalEntity.put("91330105MA27WGAY7W","1125994677125313");//思门(杭州)品牌营销策划有限公司
+        ddLegalEntity.put("91330105MA2HYCM71D","1125994676919592");//思库文化传播集团有限公司
+        ddLegalEntity.put("913301065995586166","1125994677114352");//杭州思库文化创意有限公司
+        ddLegalEntity.put("91510100MADHQM1A62","1125994677036721");//思库(成都)文化传播有限公司
+        ddLegalEntity.put("91330105MA2KGRJQ3T","1125994676949976");//光格(杭州)文化传播有限公司
+        ddLegalEntity.put("91330109MA2B2A0E3N","1125994677041739");//杭州东东腔文化创意有限公司
+        ddLegalEntity.put("","1125994336723042");//思库(浙江)文化传播有限公司
+    }
+
     @Override
     public McR saveTradingPartner(Map map) {
         String formInstId = UtilMap.getString(map, "formInstId");
@@ -55,7 +87,7 @@ public class SikuServiceImpl implements SikuService {
 
         if ("客户".equals(type)){
             //客户
-            partner.put("partnerName", "客户");//所属分类名称
+//            partner.put("parentName", "客户");//所属分类名称
             partner.put("name", UtilMap.getString(formData,"textField_mkddjwy3"));//往来单位中文名
             partner.put("partnerType", "客户");//往来关系,可选值为:"供应商"、"客户"、"供应商,客户"(既是供应商又是客户的情况下以中文逗号分隔(供应商在前))
             partner.put("partnerProperty", "公司");//往来性质,可选值为:"公司"、"个体工商户"
@@ -69,7 +101,7 @@ public class SikuServiceImpl implements SikuService {
             String hzlx = UtilMap.getString(formData, "radioField_mketkvw7");
             String freeType = UtilMap.getString(formData, "radioField_mmyoc59n");//free类别
 
-            partner.put("parentBizCode", "GYS");//所属分类业务编码
+//            partner.put("parentBizCode", "GYS");//所属分类业务编码
             partner.put("name", "个人".equals(freeType) ? UtilMap.getString(formData,"textField_mkkixdd6") : UtilMap.getString(formData,"textField_mketkvv0"));//往来单位中文名
             partner.put("partnerType", "供应商");//往来关系,可选值为:"供应商"、"客户"、"供应商,客户"(既是供应商又是客户的情况下以中文逗号分隔(供应商在前))
             partner.put("partnerProperty", "个人".equals(freeType) ? "个体工商户" : "公司");//往来性质,可选值为:"公司"、"个体工商户"
@@ -149,26 +181,23 @@ public class SikuServiceImpl implements SikuService {
         application.put("clientBizCode",UtilMap.getString(formData,"textField_mkxpe3fj"));//收票方bizCode(客户的业务编码(云票系统内维护的))与收票方开票信息字段二选一必填
         application.put("clientLegalEntityBizCode",UtilMap.getString(formData,"textField_mkddjwys"));//收票方抬头code,如果不传默认第一个(云票系统内维护的)
 
-
         String jobNumber = UtilMap.getString(formData, "textField_mo0x02kw");//申请人工号
 
         List<Map> allEmployee = MkYpUtil.getAllEmployee();
-        boolean flag = false;
+
+        String employeeId = mkyp_empId;
+
         for (Map employee : allEmployee) {
-            String employeeId = UtilMap.getString(employee, "employeeId");
-            if (jobNumber.equals(employeeId)){
-                application.put("submitterBizCode",employeeId);//提交人工号,单据状态为审批中时必填
-                application.put("applicantBizCode",employeeId);//开票申请人工号
+            String employeeId2 = UtilMap.getString(employee, "employeeId");
+            if (jobNumber.equals(employeeId2)){
+                employeeId = employeeId2;
 
-                flag = true;
                 break;
             }
         }
-        if (!flag){
-            application.put("submitterBizCode","18857526310");//提交人工号,单据状态为审批中时必填 周漂
-            application.put("applicantBizCode","18857526310");//开票申请人工号 周漂
-        }
 
+        application.put("submitterBizCode",employeeId);//提交人工号,单据状态为审批中时必填
+        application.put("applicantBizCode",employeeId);//开票申请人工号
 
         /*Map clientLegalEntityOaDto = new HashMap();//收票方开票信息(不在云票系统内维护的)与收票方bizCode(客户的业务编码)二选一必填且优先级高于收票方bizCode(客户的业务编码)(也就是当两字段都有值时,忽略客户的业务编码)
         clientLegalEntityOaDto.put("invoiceTitle",UtilMap.getString(formData,"selectField_mkxmix7e"));//名称
@@ -220,6 +249,28 @@ public class SikuServiceImpl implements SikuService {
 
         application.put("items",Arrays.asList(item));
 
+        //若为红冲发票,先作废原蓝字发票应收单
+        if ("红冲".equals(fplx)){
+            //原蓝字发票应收单查询
+            String lzlsh = UtilMap.getString(formData, "textField_mknspz7c");//原蓝字发票流水号
+            Map body1 = new HashMap();
+            body1.put("applicationInvoiceBizCodeList",Arrays.asList(lzlsh));
+            body1.put("pageSize",1);
+            body1.put("pageNum",1);
+            List<Map> receivableList = MkYpUtil.searchReceivable(body1);
+            if (!receivableList.isEmpty()){
+                Map receivable = receivableList.get(0);
+
+                String bizCode = UtilMap.getString(receivable, "bizCode");
+
+                //作废原蓝字发票应收单
+                Map body2 = new HashMap();
+                body2.put("employeeId",employeeId);
+                body2.put("bizCodeList",Arrays.asList(bizCode));
+                MkYpUtil.receivableObsolete(body2);
+            }
+        }
+
         Map result = MkYpUtil.application(Arrays.asList(application));
 
         if (!isTrue(result)){
@@ -283,8 +334,8 @@ public class SikuServiceImpl implements SikuService {
         String serviceType = UtilMap.getString(calloutParams, "serviceType");
         Map bizData = UtilMap.getMap(calloutParams, "bizData");
 
-        if ("INVOICE_VAT_INVOICED_NOTIFY_AR".equals(serviceType)){
-            //发票开具成功后回调
+        if ("INVOICE_VAT_INVOICED_NOTIFY_AR".equals(serviceType)){//开票成功逻辑移到应收单完成回调中
+            /*//发票开具成功后回调
             String bizCode = UtilMap.getString(bizData, "bizCode");//发票号码
             String invoiceNumber = UtilMap.getString(bizData, "invoiceNumber");//发票号码
             long issueDate = UtilMap.getLong(bizData, "issueDate");//开票日期
@@ -330,7 +381,7 @@ public class SikuServiceImpl implements SikuService {
             ydClient.operateData(YDParam.builder()
                     .formInstanceId(formInstanceId)
                     .updateFormDataJson(JSONObject.toJSONString(updateFormData))
-                    .build(), YDConf.FORM_OPERATION.update);
+                    .build(), YDConf.FORM_OPERATION.update);*/
 
         }else if ("INVOICE_APPLICATION_VAT_FAIL_NOTIFY_AR".equals(serviceType)){
             //开票失败后回调
@@ -338,7 +389,6 @@ public class SikuServiceImpl implements SikuService {
 
             String bizCode = UtilMap.getString(bizData, "bizCode");
 
-
             Map data = ((List<Map>)ydClient.queryData(YDParam.builder()
                     .formInstanceId(bizCode)
                     .searchCondition(JSONObject.toJSONString(UtilMap.map("serialNumberField_mknspz75",bizCode)))
@@ -352,7 +402,6 @@ public class SikuServiceImpl implements SikuService {
                     .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("radioField_mkxripcc, textareaField_mmlzqvn0","开票失败",invoiceErrorMsg)))
                     .build(), YDConf.FORM_OPERATION.update);
         }
-
     }
 
     @Override
@@ -372,43 +421,9 @@ public class SikuServiceImpl implements SikuService {
         String deptBusinessCode = "";
 
         String ydfqr = UtilMap.getString(formData, "textField_mmwvodde");//宜搭发起人工号
+        String ztcggh = UtilMap.getString(formData, "textField_mmwvfb97");//中台采购工号
 
-        if (amt >= 5000){
-            //支付金额>=5000元,每刻发起人为宜搭采购单据发起人;每刻中的【费用承担部门】实际为采购单发起人所在部门,非每刻单据发起人部门
-            Map employeeDetails = MkBxUtil.employeeDetails(UtilMap.map("employeeIds", Arrays.asList(ydfqr)));
-            if (Objects.nonNull(employeeDetails)){
-                List<Map> departments = UtilMap.getList(employeeDetails, "departments");
-                deptBusinessCode = UtilMap.getString(departments.get(0), "businessCode");
-
-                empId = ydfqr;
-            }else {
-                empId = "002";//默认沃洲洋
-                deptBusinessCode = "DI203800035494740082";//默认DI203800035494740082
-            }
-        }else {
-            //支付金额<5000元,每刻发起人为宜搭采购单据中的中台采购;每刻中的【费用承担部门】实际为采购单发起人所在部门,非每刻单据发起人部门
-            Map employeeDetails = MkBxUtil.employeeDetails(UtilMap.map("employeeIds", Arrays.asList(ydfqr)));
-            if (Objects.nonNull(employeeDetails)){
-                List<Map> departments = UtilMap.getList(employeeDetails, "departments");
-                deptBusinessCode = UtilMap.getString(departments.get(0), "businessCode");
-            }else {
-                deptBusinessCode = "DI203800035494740082";//默认DI203800035494740082
-            }
-
-            String ztcggh = UtilMap.getString(formData, "textField_mmwvfb97");//中台采购工号
-            Map employeeDetails2 = MkBxUtil.employeeDetails(UtilMap.map("employeeIds", Arrays.asList(ztcggh)));
-
-            if (Objects.nonNull(employeeDetails2)){
-                empId = ztcggh;
-            }else {
-                empId = "002";//默认沃洲洋
-            }
-        }
-
-        String submittedUserEmployeeId = empId;//提单人工号
         String legalEntityBizCode = UtilMap.getString(formData, "textField_mmd6hio7");//公司抬头编码
-        String coverUserEmployeeId = empId;//承担人工号
-        String coverDepartmentBizCode = deptBusinessCode;//承担部门编码
 
         String xqbh = UtilMap.getString(formData, "serialNumberField_mkkmij3o");//需求编号
         long ldjssj = UtilMap.getLong(formData, "dateField_mkdf8q8q");//落地结束时间
@@ -428,11 +443,27 @@ public class SikuServiceImpl implements SikuService {
                 Map body = new HashMap();
                 body.put("formCode",xqbh + "-" + index);//有值时会使用该值作为单据号
                 body.put("formSubTypeBizCode",formSubTypeBizCode);//表单类型的业务编号
-                body.put("submittedUserEmployeeId",submittedUserEmployeeId);//提单人工号
+
+                String mktdrgh = UtilMap.getString(detail, "textField_mok5mtsh");//每刻提单人工号
+                body.put("submittedUserEmployeeId",mktdrgh);//提单人工号
+                body.put("coverUserEmployeeId",mktdrgh);//承担人工号
+
+                List<Map> internalTravelPartner = new ArrayList<>();//内部参与人
+                internalTravelPartner.add(new HashMap<String,String>(){{put("employeeId",ydfqr);}});
+                internalTravelPartner.add(new HashMap<String,String>(){{put("employeeId",ztcggh);}});
+                body.put("travelPartnerInfo",new HashMap<String,List<Map>>(){{put("internalTravelPartner",internalTravelPartner);}});//参与人
+
+                //查询宜搭发起人部门
+                Map employeeDetails = MkBxUtil.employeeDetails(UtilMap.map("employeeIds", Arrays.asList(ydfqr)));
+                String coverDepartmentBizCode = mkbx_deptId;
+                if (Objects.nonNull(employeeDetails)){
+                    List<Map> departments = UtilMap.getList(employeeDetails, "departments");
+                    coverDepartmentBizCode = UtilMap.getString(departments.get(0), "businessCode");
+                }
+                body.put("coverDepartmentBizCode",coverDepartmentBizCode);//承担部门编码
+
                 body.put("reimburseName",UtilMap.getString(detail,"textareaField_mkkmij5i"));//报销事由
                 body.put("legalEntityBizCode",legalEntityBizCode);//公司抬头编码
-                body.put("coverUserEmployeeId",coverUserEmployeeId);//承担人工号
-                body.put("coverDepartmentBizCode",coverDepartmentBizCode);//承担部门编码
                 body.put("tradingPartnerBizCode",UtilMap.getString(detail,"textField_mmbmohrb"));//往来单位编码
 
 
@@ -501,14 +532,29 @@ public class SikuServiceImpl implements SikuService {
                 index ++;
                 String uuid = UtilMap.getString(detail, "textField_mmvhqm0s");//子表uuid
                 Map body = new HashMap();
-//                body.put("formCode",xqbh + "-" + uuid);//有值时会使用该值作为单据号
                 body.put("formCode",xqbh + "-" +index);//有值时会使用该值作为单据号
                 body.put("formSubTypeBizCode",formSubTypeBizCode);//表单类型的业务编号
-                body.put("submittedUserEmployeeId",submittedUserEmployeeId);//提单人工号
+
+                String mktdrgh = UtilMap.getString(detail, "textField_mok5mtsf");//每刻提单人工号
+                body.put("submittedUserEmployeeId",mktdrgh);//提单人工号
+                body.put("coverUserEmployeeId",mktdrgh);//承担人工号
+
+                List<Map> internalTravelPartner = new ArrayList<>();//内部参与人
+                internalTravelPartner.add(new HashMap<String,String>(){{put("employeeId",ydfqr);}});
+                internalTravelPartner.add(new HashMap<String,String>(){{put("employeeId",ztcggh);}});
+                body.put("travelPartnerInfo",new HashMap<String,List<Map>>(){{put("internalTravelPartner",internalTravelPartner);}});//参与人
+
+                //查询宜搭发起人部门
+                Map employeeDetails = MkBxUtil.employeeDetails(UtilMap.map("employeeIds", Arrays.asList(ydfqr)));
+                String coverDepartmentBizCode = mkbx_deptId;
+                if (Objects.nonNull(employeeDetails)){
+                    List<Map> departments = UtilMap.getList(employeeDetails, "departments");
+                    coverDepartmentBizCode = UtilMap.getString(departments.get(0), "businessCode");
+                }
+                body.put("coverDepartmentBizCode",coverDepartmentBizCode);//承担部门编码
+
                 body.put("reimburseName","FREE-" + UtilMap.getString(detail,"selectField_mkkixdd7"));//报销事由
                 body.put("legalEntityBizCode",legalEntityBizCode);//公司抬头编码
-                body.put("coverUserEmployeeId",coverUserEmployeeId);//承担人工号
-                body.put("coverDepartmentBizCode",coverDepartmentBizCode);//承担部门编码
                 body.put("tradingPartnerBizCode",UtilMap.getString(detail,"textField_mmekbfa2"));//往来单位编码
 
                 Map customObject = new HashMap();
@@ -831,6 +877,9 @@ public class SikuServiceImpl implements SikuService {
             for (Map expenseValue : expenseValueList) {
                 Map deductionList = UtilMap.getMap(expenseValue, "deductionList");//当前对公费用核销的数据(当前到票核销场景核销了哪些“预付未到票”记录)
 
+                Map expenseDeductionTaxAmount = UtilMap.getMap(expenseValue, "expenseDeductionTaxAmount");//费用级抵扣税额(消费币种)
+                Double sj = UtilMap.getDouble(expenseDeductionTaxAmount, "amount");//每刻实际税金
+
                 List<Map> deductionValueList = UtilMap.getList(deductionList, "value");
 
                 Map deductionValue = deductionValueList.get(0);
@@ -839,8 +888,8 @@ public class SikuServiceImpl implements SikuService {
                 String targetFormCode = UtilMap.getString(deductionValue, "targetFormCode");//核销报销单编号
 
                 if (targetFormCode.contains("需求") || targetFormCode.contains("采购")){
-                    //更新宜搭核销金额
-                    updateYdDeduction(targetFormCode,deductionAmount);
+                    //更新宜搭核销金额及税金
+                    updateYdDeduction(targetFormCode,deductionAmount,sj);
                 }
             }
 
@@ -866,9 +915,13 @@ public class SikuServiceImpl implements SikuService {
                 return;
             }
         }else {
-            amt = UtilMap.getDouble(reimburseDetailInfo, "paymentAmount");//应付金额
+            Map paymentAmount = UtilMap.getMap(reimburseDetailInfo, "paymentAmount");
+            amt = UtilMap.getDouble(paymentAmount, "amount");//应付金额
+
         }
 
+        long approvedAt = UtilMap.getLong(reimburseDetailInfo, "approvedAt");//审批通过时间
+
         String[] split = formCode.split("-");
 
         String bh = split[0];//采购需求编号/直接采购单编号
@@ -906,6 +959,7 @@ public class SikuServiceImpl implements SikuService {
                         }
 
                         detailMap.put("numberField_mmvqom6l",yfkje + amt);
+                        detailMap.put("dateField_mnh6e4zy",approvedAt);
                     }
                     updateDetailList.add(detailMap);
                 }
@@ -927,6 +981,7 @@ public class SikuServiceImpl implements SikuService {
                         }
 
                         detailMap.put("numberField_mmvqs9h6",yfkje + amt);
+                        detailMap.put("dateField_mnh6e4zw",approvedAt);
                     }
                     updateDetailList.add(detailMap);
                 }
@@ -973,6 +1028,7 @@ public class SikuServiceImpl implements SikuService {
                         }
 
                         detailMap.put("numberField_mmvqom6k",yfkje + amt);
+                        detailMap.put("dateField_mnh6e4zy",approvedAt);
                     }
                     updateDetailList.add(detailMap);
                 }
@@ -994,6 +1050,7 @@ public class SikuServiceImpl implements SikuService {
                         }
 
                         detailMap.put("numberField_mmvqom6l",yfkje + amt);
+                        detailMap.put("dateField_mnh6e4zw",approvedAt);
                     }
                     updateDetailList.add(detailMap);
                 }
@@ -1015,7 +1072,7 @@ public class SikuServiceImpl implements SikuService {
     }
 
     //更新宜搭采购已核销金额
-    private void updateYdDeduction(String formCode, Double deductionAmount) {
+    private void updateYdDeduction(String formCode, Double deductionAmount,Double sj) {
         String[] split = formCode.split("-");
         String bh = split[0];
         int index = Integer.parseInt(split[1]);
@@ -1043,8 +1100,21 @@ public class SikuServiceImpl implements SikuService {
                     Map detailMap = new HashMap();
                     if (index == UtilMap.getInt(detail, "numberField_mn36ykxx")){
                         Double yhxje = UtilMap.getDouble(detail, "numberField_mniatky8");//已核销金额
+                        Double ythje = UtilMap.getDouble(detail, "numberField_mn4g182f");//已退回金额
+                        Double mksjsj = UtilMap.getDouble(detail, "numberField_mob8gv4p");//每刻实际税金
+                        Double ydsj = UtilMap.getDouble(detail, "numberField_mmsvi56x");//税金
+                        Double ydcgje = UtilMap.getDouble(detail, "numberField_mkkmij5e");//采购金额
 
                         detailMap.put("numberField_mniatky8",yhxje + deductionAmount);
+                        detailMap.put("numberField_mob8gv4p",mksjsj + sj);//每刻实际税金
+
+                        //若采购金额等于已核销金额+本次核销金额+已退回金额
+                        if (ydcgje == yhxje + deductionAmount + ythje){
+                            Double totalSj = UtilMap.getDouble(ydFormData, "numberField_mkkmij6k");//总税金
+
+                            updateFormData.put("numberField_mkkmij6k",totalSj - ydsj + sj);//总税金
+                            updateFormData.put("numberField_mob8gv4v",-ydsj + sj);//最新税金插值
+                        }
                     }
                     updateDetailList.add(detailMap);
                 }
@@ -1056,8 +1126,21 @@ public class SikuServiceImpl implements SikuService {
                     Map detailMap = new HashMap();
                     if (index == UtilMap.getInt(detail, "numberField_mn36ykxz")){
                         Double yhxje = UtilMap.getDouble(detail, "numberField_mniatkya");//已核销金额
+                        Double ythje = UtilMap.getDouble(detail, "numberField_mn4g182g");//已退回金额
+                        Double mksjsj = UtilMap.getDouble(detail, "numberField_mob8gv4q");//每刻实际税金
+                        Double ydsj = UtilMap.getDouble(detail, "numberField_mn3zekbx");//税金
+                        Double ydcgje = UtilMap.getDouble(detail, "numberField_mkkmij6p");//采购金额
 
                         detailMap.put("numberField_mniatkya",yhxje + deductionAmount);
+                        detailMap.put("numberField_mob8gv4q",mksjsj + sj);//每刻实际税金
+
+                        //若采购金额等于已核销金额+本次核销金额+已退回金额
+                        if (ydcgje == yhxje + deductionAmount + ythje){
+                            Double totalSj = UtilMap.getDouble(ydFormData, "numberField_mkkmij6k");//总税金
+
+                            updateFormData.put("numberField_mkkmij6k",totalSj - ydsj + sj);//总税金
+                            updateFormData.put("numberField_mob8gv4v",-ydsj + sj);//最新税金插值
+                        }
                     }
                     updateDetailList.add(detailMap);
                 }
@@ -1089,8 +1172,21 @@ public class SikuServiceImpl implements SikuService {
                     Map detailMap = new HashMap();
                     if (index == UtilMap.getInt(detail, "numberField_mn36ykxx")){
                         Double yhxje = UtilMap.getDouble(detail, "numberField_mniatky8");//已核销金额
+                        Double ythje = UtilMap.getDouble(detail, "numberField_mn4g182f");//已退回金额
+                        Double mksjsj = UtilMap.getDouble(detail, "numberField_mob8gv4p");//每刻实际税金
+                        Double ydsj = UtilMap.getDouble(detail, "numberField_mmsvi56x");//税金
+                        Double ydcgje = UtilMap.getDouble(detail, "numberField_mkkmij5e");//采购金额
 
                         detailMap.put("numberField_mniatky8",yhxje + deductionAmount);
+                        detailMap.put("numberField_mob8gv4p",mksjsj + sj);//每刻实际税金
+
+                        //若采购金额等于已核销金额+本次核销金额+已退回金额
+                        if (ydcgje == yhxje + deductionAmount + ythje){
+                            Double totalSj = UtilMap.getDouble(ydFormData, "numberField_mkkmij6k");//总税金
+
+                            updateFormData.put("numberField_mkkmij6k",totalSj - ydsj + sj);//总税金
+                            updateFormData.put("numberField_mob8gv4v",-ydsj + sj);//最新税金插值
+                        }
                     }
                     updateDetailList.add(detailMap);
                 }
@@ -1102,8 +1198,21 @@ public class SikuServiceImpl implements SikuService {
                     Map detailMap = new HashMap();
                     if (index == UtilMap.getInt(detail, "numberField_mn36ykxz")){
                         Double yhxje = UtilMap.getDouble(detail, "numberField_mniatkya");//已核销金额
+                        Double ythje = UtilMap.getDouble(detail, "numberField_mn4g182g");//已退回金额
+                        Double mksjsj = UtilMap.getDouble(detail, "numberField_mob8gv4q");//每刻实际税金
+                        Double ydsj = UtilMap.getDouble(detail, "numberField_mn3zekbx");//税金
+                        Double ydcgje = UtilMap.getDouble(detail, "numberField_mkkmij6p");//采购金额
 
                         detailMap.put("numberField_mniatkya",yhxje + deductionAmount);
+                        detailMap.put("numberField_mob8gv4q",mksjsj + sj);//每刻实际税金
+
+                        //若采购金额等于已核销金额+本次核销金额+已退回金额
+                        if (ydcgje == yhxje + deductionAmount + ythje){
+                            Double totalSj = UtilMap.getDouble(ydFormData, "numberField_mkkmij6k");//总税金
+
+                            updateFormData.put("numberField_mkkmij6k",totalSj - ydsj + sj);//总税金
+                            updateFormData.put("numberField_mob8gv4v",-ydsj + sj);//最新税金插值
+                        }
                     }
                     updateDetailList.add(detailMap);
                 }
@@ -1135,44 +1244,8 @@ public class SikuServiceImpl implements SikuService {
         String deptBusinessCode = "";
 
         String ydfqr = UtilMap.getString(formData, "textField_mmwvodde");//宜搭发起人工号
-
-        if (amt >= 5000){
-            //支付金额>=5000元,每刻发起人为宜搭采购单据发起人;每刻中的【费用承担部门】实际为采购单发起人所在部门,非每刻单据发起人部门
-            Map employeeDetails = MkBxUtil.employeeDetails(UtilMap.map("employeeIds", Arrays.asList(ydfqr)));
-            if (Objects.nonNull(employeeDetails)){
-                List<Map> departments = UtilMap.getList(employeeDetails, "departments");
-                deptBusinessCode = UtilMap.getString(departments.get(0), "businessCode");
-
-                empId = ydfqr;
-            }else {
-                empId = "002";//默认沃洲洋
-                deptBusinessCode = "DI203800035494740082";//默认DI203800035494740082
-            }
-        }else {
-            //支付金额<5000元,每刻发起人为宜搭采购单据中的中台采购;每刻中的【费用承担部门】实际为采购单发起人所在部门,非每刻单据发起人部门
-            Map employeeDetails = MkBxUtil.employeeDetails(UtilMap.map("employeeIds", Arrays.asList(ydfqr)));
-            if (Objects.nonNull(employeeDetails)){
-                List<Map> departments = UtilMap.getList(employeeDetails, "departments");
-                deptBusinessCode = UtilMap.getString(departments.get(0), "businessCode");
-            }else {
-                deptBusinessCode = "DI203800035494740082";//默认DI203800035494740082
-            }
-
-            String ztcggh = UtilMap.getString(formData, "textField_mmwvfb97");//中台采购工号
-            Map employeeDetails2 = MkBxUtil.employeeDetails(UtilMap.map("employeeIds", Arrays.asList(ztcggh)));
-
-            if (Objects.nonNull(employeeDetails2)){
-                empId = ztcggh;
-            }else {
-                empId = "002";//默认沃洲洋
-            }
-        }
-
-        String submittedUserEmployeeId = empId;//提单人工号
+        String ztcggh = UtilMap.getString(formData, "textField_mmwvfb97");//中台采购工号
         String legalEntityBizCode = UtilMap.getString(formData, "textField_mmd6hio7");//公司抬头编码
-        String coverUserEmployeeId = empId;//承担人工号
-        String coverDepartmentBizCode = deptBusinessCode;//承担部门编码
-
         String xqbh = UtilMap.getString(formData, "serialNumberField_mkkmij3o");//需求编号
         long ldjssj = UtilMap.getLong(formData, "dateField_mkdf8q8q");//落地结束时间
         String isFree = "FREE采购".equals(UtilMap.getString(formData, "radioField_mkf2quln")) ? "是" : "否";//是否free
@@ -1187,16 +1260,32 @@ public class SikuServiceImpl implements SikuService {
             for (Map detail : detailList) {
                 index++;
                 String uuid = UtilMap.getString(detail, "textField_mmvhqm0q");//子表uuid
+
                 Map body = new HashMap();
                 body.put("formCode",xqbh + "-" + index);//有值时会使用该值作为单据号
                 body.put("formSubTypeBizCode",formSubTypeBizCode);//表单类型的业务编号
-                body.put("submittedUserEmployeeId",submittedUserEmployeeId);//提单人工号
-                body.put("reimburseName",UtilMap.getString(detail,"textareaField_mkkmij5i"));//报销事由
-                body.put("legalEntityBizCode",legalEntityBizCode);//公司抬头编码
-                body.put("coverUserEmployeeId",coverUserEmployeeId);//承担人工号
+
+                String mktdrgh = UtilMap.getString(detail, "textField_mok5mtsh");//每刻提单人工号
+                body.put("submittedUserEmployeeId",mktdrgh);//提单人工号
+                body.put("coverUserEmployeeId",mktdrgh);//承担人工号
+
+                List<Map> internalTravelPartner = new ArrayList<>();//内部参与人
+                internalTravelPartner.add(new HashMap<String,String>(){{put("employeeId",ydfqr);}});
+                internalTravelPartner.add(new HashMap<String,String>(){{put("employeeId",ztcggh);}});
+                body.put("travelPartnerInfo",new HashMap<String,List<Map>>(){{put("internalTravelPartner",internalTravelPartner);}});//参与人
+
+                //查询宜搭发起人部门
+                Map employeeDetails = MkBxUtil.employeeDetails(UtilMap.map("employeeIds", Arrays.asList(ydfqr)));
+                String coverDepartmentBizCode = mkbx_deptId;
+                if (Objects.nonNull(employeeDetails)){
+                    List<Map> departments = UtilMap.getList(employeeDetails, "departments");
+                    coverDepartmentBizCode = UtilMap.getString(departments.get(0), "businessCode");
+                }
                 body.put("coverDepartmentBizCode",coverDepartmentBizCode);//承担部门编码
-                body.put("tradingPartnerBizCode",UtilMap.getString(detail,"textField_mmbmohrb"));//往来单位编码
 
+                body.put("legalEntityBizCode",legalEntityBizCode);//公司抬头编码
+                body.put("reimburseName",UtilMap.getString(detail,"textareaField_mkkmij5i"));//报销事由
+                body.put("tradingPartnerBizCode",UtilMap.getString(detail,"textField_mmbmohrb"));//往来单位编码
 
                 Map customObject = new HashMap();
                 customObject.put("CF4",new HashMap<String,Long>(){{put("currentTime",ldjssj);}});//落地结束时间
@@ -1262,14 +1351,30 @@ public class SikuServiceImpl implements SikuService {
                 index ++;
                 String uuid = UtilMap.getString(detail, "textField_mmvhqm0s");//子表uuid
                 Map body = new HashMap();
-//                body.put("formCode",xqbh + "-" + uuid);//有值时会使用该值作为单据号
                 body.put("formCode",xqbh + "-" +index);//有值时会使用该值作为单据号
                 body.put("formSubTypeBizCode",formSubTypeBizCode);//表单类型的业务编号
-                body.put("submittedUserEmployeeId",submittedUserEmployeeId);//提单人工号
+
+                String mktdrgh = UtilMap.getString(detail, "textField_mok5mtsf");//每刻提单人工号
+                body.put("submittedUserEmployeeId",mktdrgh);//提单人工号
+                body.put("coverUserEmployeeId",mktdrgh);//承担人工号
+
+                List<Map> internalTravelPartner = new ArrayList<>();//内部参与人
+                internalTravelPartner.add(new HashMap<String,String>(){{put("employeeId",ydfqr);}});
+                internalTravelPartner.add(new HashMap<String,String>(){{put("employeeId",ztcggh);}});
+                body.put("travelPartnerInfo",new HashMap<String,List<Map>>(){{put("internalTravelPartner",internalTravelPartner);}});//参与人
+
+                //查询宜搭发起人部门
+                Map employeeDetails = MkBxUtil.employeeDetails(UtilMap.map("employeeIds", Arrays.asList(ydfqr)));
+                String coverDepartmentBizCode = mkbx_deptId;
+                if (Objects.nonNull(employeeDetails)){
+                    List<Map> departments = UtilMap.getList(employeeDetails, "departments");
+                    coverDepartmentBizCode = UtilMap.getString(departments.get(0), "businessCode");
+                }
+                body.put("coverDepartmentBizCode",coverDepartmentBizCode);//承担部门编码
+
+
                 body.put("reimburseName","FREE-" + UtilMap.getString(detail,"selectField_mkkixdd7"));//报销事由
                 body.put("legalEntityBizCode",legalEntityBizCode);//公司抬头编码
-                body.put("coverUserEmployeeId",coverUserEmployeeId);//承担人工号
-                body.put("coverDepartmentBizCode",coverDepartmentBizCode);//承担部门编码
                 body.put("tradingPartnerBizCode",UtilMap.getString(detail,"textField_mmekbfa2"));//往来单位编码
 
                 Map customObject = new HashMap();
@@ -1542,12 +1647,12 @@ public class SikuServiceImpl implements SikuService {
 
                     Double yzf = UtilMap.getDouble(ydFormData, "numberField_mkf2qumf");//已支付
 
-                    ydFormData.put("numberField_mkf2qumf",yzf + amt);//已支付
-                    ydFormData.put("numberField_mnibjld0",amt);//最新支付金额
+                    updateFormData.put("numberField_mkf2qumf",yzf + amt);//已支付
+                    updateFormData.put("numberField_mnibjld0",amt);//最新支付金额
 
                     ydClient.operateData(YDParam.builder()
                             .formInstanceId(formInstanceId)
-                            .updateFormDataJson(JSONObject.toJSONString(ydFormData))
+                            .updateFormDataJson(JSONObject.toJSONString(updateFormData))
                             .build(), YDConf.FORM_OPERATION.update);
                 }else {
                     //直接采购结算单
@@ -1624,6 +1729,12 @@ public class SikuServiceImpl implements SikuService {
     @Async
     @Override
     public void invoiceWriteBack5(Map map) {
+        //防止查询不到单据详情
+        try {
+            Thread.sleep(3000);
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
         String formCode = UtilMap.getString(map, "formCode");
 
         Map repayDetailInfo = MkBxUtil.repayDetailInfo(formCode);
@@ -2023,8 +2134,8 @@ public class SikuServiceImpl implements SikuService {
 
             empId = sqrgh;
         }else {
-            empId = "002";//默认沃洲洋
-            deptBusinessCode = "DI203800035494740082";//默认DI203800035494740082
+            empId = mkbx_empId;
+            deptBusinessCode = mkbx_deptId;
         }
 
         if ("直接采购".equals(type)){
@@ -2113,6 +2224,147 @@ public class SikuServiceImpl implements SikuService {
         return McR.success();
     }
 
+    @Async
+    @Override
+    public void invoiceWriteBack9(Map map) {
+        Map calloutParams = UtilMap.getMap(map, "calloutParams");
+        String serviceType = UtilMap.getString(calloutParams, "serviceType");
+        Map bizData = UtilMap.getMap(calloutParams, "bizData");
+
+        if ("RECEIVABLE_AR_COMPLETED_NOTIFY_AR".equals(serviceType)){
+            List<Map> invoiceList = UtilMap.getList(bizData, "invoiceList");
+
+            Map invoiceMap = invoiceList.get(0);
+
+            String invoiceNumber = UtilMap.getString(invoiceMap, "invoiceNumber");//发票号码
+            long formDate = UtilMap.getLong(invoiceMap, "formDate");//开票日期
+
+            String invoiceApplicationBizCode = ((List<String>)UtilMap.getList(bizData, "invoiceApplicationBizCodes")).get(0);//开票申请单编号
+
+            Map updateFormData = new HashMap();
+            updateFormData.put("radioField_mkxripcc","开票成功");
+            updateFormData.put("textField_mkxripc6",invoiceNumber);
+            updateFormData.put("dateField_mnfpbwpd",formDate);
+            updateFormData.put("textareaField_mmlzqvn0","");
+
+            //发票下载信息查询
+            Map invoiceInfo = MkYpUtil.getInvoiceInfo(invoiceNumber);
+
+            if (Objects.nonNull(invoiceInfo)){
+                String pdfUrl = UtilMap.getString(invoiceInfo, "pdfUrl");//发票下载地址
+                String downloadPageUrl = UtilMap.getString(invoiceInfo, "downloadPageUrl");//发票下载页面地址
+
+                if (Strings.isNotBlank(pdfUrl)){
+                    String fileName = invoiceNumber + ".pdf";
+                    String downloadPath = downloadFilePath + fileName;
+                    downloadFile(pdfUrl,downloadPath);//下载pdf发票
+
+                    String downloadUri = downloadUrl + "files/" + fileName + "?option=download";
+                    String previewUri = downloadUrl + "files/" + fileName + "?option=preview";
+
+                    Map attachmentField = new HashMap();
+                    attachmentField.put("downloadUrl",downloadUri);
+                    attachmentField.put("name",fileName);
+                    attachmentField.put("previewUrl",previewUri);
+                    attachmentField.put("url",downloadUri);
+                    attachmentField.put("ext","pdf");
+                    updateFormData.put("attachmentField_mkxripc5",Arrays.asList(attachmentField));
+                }
+
+                if (Strings.isNotBlank(downloadPageUrl)){
+                    updateFormData.put("textField_mm3aixk0",downloadPageUrl);
+                }
+            }
+
+            //回写宜搭
+            Map data = ((List<Map>)ydClient.queryData(YDParam.builder()
+                    .searchCondition(JSONObject.toJSONString(UtilMap.map("serialNumberField_mknspz75",invoiceApplicationBizCode)))
+                    .formUuid("FORM-A9A47B0365DB437F8F4C8E01B4468220K7GU")
+                    .build(), YDConf.FORM_QUERY.retrieve_list).getData()).get(0);
+
+            String formInstanceId = UtilMap.getString(data, "formInstanceId");
+
+            ydClient.operateData(YDParam.builder()
+                    .formInstanceId(formInstanceId)
+                    .updateFormDataJson(JSONObject.toJSONString(updateFormData))
+                    .build(), YDConf.FORM_OPERATION.update);
+        }
+    }
+
+    @Override
+    public McR ddProject(Map map) {
+        String formInstId = UtilMap.getString(map, "formInstId");
+        String type = UtilMap.getString(map, "type");
+
+        Map formData = ydClient.queryData(YDParam.builder()
+                .formInstanceId(formInstId)
+                .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
+
+        String projectCode = UtilMap.getString(formData, "serialNumberField_mknemyna");//项目流水号
+        String projectName = UtilMap.getString(formData, "textField_mkdedkvu");//项目名称
+        String projectProgress = UtilMap.getString(formData, "selectField_mkdf8q80");//项目进度
+        String projectManager = UtilMap.getString(formData, "textField_mo8lkotd");//项目负责人工号
+        List<String> projectMember = UtilMap.getList(formData, "multiSelectField_mo9iilfl");//项目成员工号
+        String ztcg = UtilMap.getString(formData, "textField_mo9iilfm");//中台采购工号
+
+        List<String> leader_employee_id = new ArrayList<>();
+        leader_employee_id.add(projectManager);//第一个为主负责人,后续为其他负责人
+        leader_employee_id.addAll(projectMember);
+        leader_employee_id.add(ztcg);
+        //leader_employee_id去重
+        leader_employee_id = leader_employee_id.stream().distinct().collect(Collectors.toList());
+
+        String htqygssh = UtilMap.getString(formData, "textField_mo9nav1d");//合同签约公司税号
+
+        if ("add".equals(type)){//新增
+            String startDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());//项目开始时间
+            //当前时间+一年半
+            Calendar calendar = Calendar.getInstance();
+            calendar.setTime(new Date());
+            calendar.add(Calendar.YEAR, 1);
+            calendar.add(Calendar.MONTH, 6);
+            String endDate = new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime());//项目结束时间
+
+            Map body = new HashMap();
+            body.put("out_budget_id",projectCode);
+            body.put("name",projectName);
+            body.put("type",2);
+            body.put("budget_cycle",0);
+            body.put("total_quota",0);
+            body.put("member_used",2);//0 :全员可见 1:项目成员可见 2:公司主体可见
+            body.put("legal_entity_id",ddLegalEntity.get(htqygssh));//项目所属公司主体ID
+            body.put("start_date",startDate);
+            body.put("expiry_date",endDate);
+            body.put("leader_employee_id",JSONObject.toJSONString(leader_employee_id));
+
+            Map result = QyddUtil.BudgetCenterAdd(body);
+
+            return McR.success(result);
+        }else if ("update".equals(type)){//更新
+            Map body = new HashMap();
+            body.put("out_budget_id",projectCode);
+            body.put("name",projectName);
+            body.put("type",2);
+            body.put("member_used",2);//0 :全员可见 1:项目成员可见 2:公司主体可见
+            body.put("legal_entity_id",ddLegalEntity.get(htqygssh));//项目所属公司主体ID
+            body.put("leader_employee_id",JSONObject.toJSONString(leader_employee_id));
+
+            Map result = QyddUtil.BudgetCenterEdit(body);
+
+            return McR.success(result);
+        }else{//封账
+            Map body = new HashMap();
+            body.put("out_budget_id",projectCode);
+            body.put("name",projectName);
+            body.put("type",2);
+            body.put("expiry_date",new SimpleDateFormat("yyyy-MM-dd").format(new Date()));//项目结束时间  封账时间
+
+            Map result = QyddUtil.BudgetCenterEdit(body);
+
+            return McR.success(result);
+        }
+    }
+
     private static String getMkStrValue(Map formData, String entityName) {
         Map title = UtilMap.getMap(formData, entityName);
         Map value = UtilMap.getMap(title, "value");
@@ -2190,6 +2442,7 @@ public class SikuServiceImpl implements SikuService {
                         Double ythje = UtilMap.getDouble(detail, "numberField_mn4g182f");//已退回金额
 
                         detailMap.put("numberField_mn4g182f",ythje + amount);
+                        detailMap.put("selectField_mmvhqm0p","部分退款");
                     }
                     updateDetailList.add(detailMap);
                 }
@@ -2203,12 +2456,17 @@ public class SikuServiceImpl implements SikuService {
                         Double ythje = UtilMap.getDouble(detail, "numberField_mn4g182g");//已退回金额
 
                         detailMap.put("numberField_mn4g182g",ythje + amount);
+                        detailMap.put("selectField_mkkmij6a","部分退款");
                     }
                     updateDetailList.add(detailMap);
                 }
                 updateFormData.put("tableField_mkkmij61",updateDetailList);
             }
 
+            Double totalAmt = UtilMap.getDouble(ydFormData, "numberField_mn4g5e28");//已退回
+
+            updateFormData.put("numberField_mn4g5e28",totalAmt + amount);
+
             ydClient.operateData(YDParam.builder()
                     .formInstanceId(formInstanceId)
                     .updateFormDataJson(JSONObject.toJSONString(updateFormData))
@@ -2236,6 +2494,7 @@ public class SikuServiceImpl implements SikuService {
                         Double ythje = UtilMap.getDouble(detail, "numberField_mn4g182f");//已退回金额
 
                         detailMap.put("numberField_mn4g182f",ythje + amount);
+                        detailMap.put("selectField_mmvhtdy0","部分退款");
                     }
                     updateDetailList.add(detailMap);
                 }
@@ -2249,12 +2508,17 @@ public class SikuServiceImpl implements SikuService {
                         Double ythje = UtilMap.getDouble(detail, "numberField_mn4g182g");//已退回金额
 
                         detailMap.put("numberField_mn4g182g",ythje + amount);
+                        detailMap.put("selectField_mkkmij6a","部分退款");
                     }
                     updateDetailList.add(detailMap);
                 }
                 updateFormData.put("tableField_mkkmij61",updateDetailList);
             }
 
+            Double totalAmt = UtilMap.getDouble(ydFormData, "numberField_mn4g5e28");//已退回
+
+            updateFormData.put("numberField_mn4g5e28",totalAmt + amount);
+
             ydClient.operateData(YDParam.builder()
                     .formInstanceId(formInstanceId)
                     .updateFormDataJson(JSONObject.toJSONString(updateFormData))

+ 1 - 0
mjava-siku/src/main/java/com/malk/siku/service/impl/SikuTaskServiceImpl.java

@@ -29,6 +29,7 @@ public class SikuTaskServiceImpl implements SikuTaskService {
     @Override
     public void syncLoanManage() {
         try {
+            log.info("开始同步借还款台账");
             //删除宜搭借款台账
             List<List<String>> formInstanceIdListList = new ArrayList<>();//实例id集合,每100条
 

+ 4 - 4
mjava-siku/src/main/java/com/malk/siku/utils/MkBxUtil.java

@@ -17,14 +17,14 @@ import java.util.*;
 @Slf4j
 public class MkBxUtil {
     //测试环境
-    private final static String appCode = "AP52Y01LHHTAP9";
+    /*private final static String appCode = "AP52Y01LHHTAP9";
     private final static String appSecret = "N4WuERLteAUPaWebnsHy";
-    private final static String host = "ng.maycur.com";
+    private final static String host = "ng.maycur.com";*/
 
     //生产环境
-    /*private final static String appCode = "AP52RG1SCG8S6L";
+    private final static String appCode = "AP52RG1SCG8S6L";
     private final static String appSecret = "YFTbD2MviqUwztBTbMWd";
-    private final static String host = "ng.maycur.com";*/
+    private final static String host = "ng.maycur.com";
 
     private final Object $lock = new Object[0];
 

+ 34 - 4
mjava-siku/src/main/java/com/malk/siku/utils/MkYpUtil.java

@@ -19,14 +19,14 @@ import java.util.Map;
 @Slf4j
 public class MkYpUtil {
     //测试环境
-    private final static String appCode = "AP53EP1SVDS1N9";
+    /*private final static String appCode = "AP53EP1SVDS1N9";
     private final static String appSecret = "qF4nm3nPnyXYcrWcr5jl";
-    private final static String host = "pms-uat.maycur.com";
+    private final static String host = "pms-uat.maycur.com";*/
 
     //生产环境
-    /*private final static String appCode = "AP565SLVOI76UA";
+    private final static String appCode = "AP565SLVOI76UA";
     private final static String appSecret = "sGoMNMSbaw4MWLLbUTtPye2k6trtfIs1";
-    private final static String host = "pms.maycur.com";*/
+    private final static String host = "pms.maycur.com";
 
     private final Object $lock = new Object[0];
 
@@ -117,6 +117,36 @@ public class MkYpUtil {
         return data;
     }
 
+    //已完成发票数据查询接口V2
+    public static Map getInvoiceInfo(String invoiceNumber){
+        Map body = new HashMap();
+        body.put("searchType","INVOICE_VAT");
+        body.put("invoiceNumber",invoiceNumber);
+        body.put("pageSize",1);
+        body.put("pageNum",1);
+
+        Map result = (Map) JSONObject.parse(UtilHttp.doPost("https://" + host + "/api/ar/openapi/invoice/v2/search", MkYpUtil.initTokenHeader(), null, body,(Map) null));
+
+        log.info("Result:{}",result);
+
+        Map data = UtilMap.getMap(result, "data");
+
+        List<Map> list = UtilMap.getList(data, "list");
+
+        if (!list.isEmpty()){
+            return list.get(0);
+        }else {
+            return null;
+        }
+    }
+
+    //应收单作废接口
+    public static void receivableObsolete(Map body){
+        Map result = (Map) JSONObject.parse(UtilHttp.doPost("https://" + host + "/api/ar/openapi/receivable_oa/obsolete", MkYpUtil.initTokenHeader(), null, body,(Map) null));
+
+        log.info("Result:{}",result);
+    }
+
     private static String getSecret(String appCode, String appSecret, long timeMillis){
         log.info("time:{}",timeMillis);
 

+ 178 - 0
mjava-siku/src/main/java/com/malk/siku/utils/QyddUtil.java

@@ -0,0 +1,178 @@
+package com.malk.siku.utils;
+
+import com.alibaba.fastjson.JSONObject;
+import com.malk.utils.UtilHttp;
+import com.malk.utils.UtilMap;
+import com.malk.utils.UtilToken;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.*;
+
+/**
+ * 企业滴滴
+ */
+@Slf4j
+public class QyddUtil {
+    private static String client_id = "3295ee5021a0dd6436d18f56e7c761c6";
+    private static String client_secret = "fe5539d17722035cba70a2e6220c43a4";
+    private static String phone = "18857526310";
+    private static String signKey = "038bD3BAb4a25D84dc96";
+    private static String grant_type = "client_credentials";
+    private static String company_id = "1125994055637379";
+    private static String host = "api.es.xiaojukeji.com";
+
+    private static final Long EXPIRES_IN = 1800000L;
+
+    public static String getToken(){
+        String accessToken = "";
+
+        String token = UtilToken.get("invalid-token-qydd");
+
+        if (StringUtils.isNotBlank(token)) {
+            accessToken = token;
+        } else {
+            //企业滴授权认证
+            long timeMillis = System.currentTimeMillis();
+
+            Map<String, Object> body = new HashMap<>();
+            body.put("client_id", client_id);
+            body.put("client_secret", client_secret);
+            body.put("grant_type", grant_type);
+            body.put("phone", phone);
+            body.put("timestamp", timeMillis);
+
+            String sign = genSign(body, signKey, 0);
+
+            System.out.println("sign:"+sign);
+            System.out.println("timestamp:" + timeMillis);
+
+            body.put("sign", sign);
+            Map result = (Map) JSONObject.parse(UtilHttp.doPost("https://" + host + "/river/Auth/authorize", null, null, body));
+
+            log.info("result:{}",result);
+
+            accessToken = UtilMap.getString(result, "access_token");
+
+            UtilToken.put("invalid-token-qydd", accessToken, EXPIRES_IN);
+        }
+
+        return accessToken;
+    }
+
+    public static Map BudgetCenterAdd(Map body){
+        body.put("client_id",client_id);
+        body.put("company_id",company_id);
+        body.put("access_token",getToken());
+        body.put("timestamp",System.currentTimeMillis()/1000);
+        String sign = genSign(body, signKey, 0);
+        body.put("sign",sign);
+        String s = UtilHttp.doPost("https://" + host + "/river/BudgetCenter/add", null, null, body);
+
+        log.info("result:{}",s);
+
+        Map result = (Map)JSONObject.parse(s);
+
+        return result;
+    }
+
+    public static Map BudgetCenterEdit(Map body){
+        body.put("client_id",client_id);
+        body.put("company_id",company_id);
+        body.put("access_token",getToken());
+        body.put("timestamp",System.currentTimeMillis()/1000);
+        String sign = genSign(body, signKey, 0);
+        body.put("sign",sign);
+        String s = UtilHttp.doPost("https://" + host + "/river/BudgetCenter/edit", null, null, body);
+
+        log.info("result:{}",s);
+
+        Map result = (Map)JSONObject.parse(s);
+
+        return result;
+    }
+
+    //java md5算法
+    public static String md5(String plainText) {
+        byte[] secretBytes = null;
+        try {
+            MessageDigest md  = MessageDigest.getInstance("MD5");
+            md.update(plainText.getBytes("utf-8"));
+            secretBytes = md.digest();
+        }
+        catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("no such algorithm!");
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException(e);
+        }
+
+
+        String md5code = new BigInteger(1, secretBytes).toString(16);
+        int length = md5code.length();
+        for (int i = 0; i < 32 - length; i++) {
+            md5code = "0" + md5code;
+        }
+        return md5code;
+    }
+    //java sha256算法
+    public static String sha256Hex(String input) {
+        try {
+            // 创建一个MessageDigest实例,并指定使用SHA-256算法
+            MessageDigest digest = MessageDigest.getInstance("SHA-256");
+
+            // 将输入字符串转换为字节数组,并更新摘要
+            byte[] hash = digest.digest(input.getBytes(StandardCharsets.UTF_8));
+
+            // 将字节数组转换为十六进制字符串
+            StringBuilder hexString = new StringBuilder();
+            for (byte b : hash) {
+                String hex = Integer.toHexString(0xff & b);
+                if (hex.length() == 1) hexString.append('0');
+                hexString.append(hex);
+            }
+
+            return hexString.toString();
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static String genSign(Map<String, Object> params, String signKey, Integer signMethod) {
+        params.put("sign_key", signKey);
+        String result = "";
+        try {
+            List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(params.entrySet());
+            Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() {
+                public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
+                    return (o1.getKey()).compareTo(o2.getKey());
+                }
+            });
+            // 构造签名键值对的格式
+            for (Map.Entry<String, Object> item : infoIds) {
+                if (item.getKey() != null || item.getKey() != "") {
+                    String key = item.getKey();
+                    String val = (item.getValue()+"").trim();
+                    if (result == "") {
+                        result += key + "=" + val;
+                    } else {
+                        result += "&" + key + "=" + val;
+                    }
+                }
+            }
+            //System.out.println(result);
+        } catch(Exception e) {
+            throw new RuntimeException("error");
+        }
+        if(signMethod == 1) {
+            return sha256Hex(result);
+        }
+        return md5(result);
+    }
+
+
+}

+ 104 - 0
mjava-siku/src/test/java/com.malk.siku/SkTest.java

@@ -9,6 +9,13 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.junit4.SpringRunner;
 
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.*;
+
 @Slf4j
 @SpringBootTest
 @RunWith(SpringRunner.class)
@@ -54,6 +61,103 @@ public class SkTest {
         sikuTaskService.syncLoanManage();
     }
 
+    //java md5算法
+    public static String md5(String plainText)
+    {
+        byte[] secretBytes = null;
+        try {
+            MessageDigest md  = MessageDigest.getInstance("MD5");
+            md.update(plainText.getBytes("utf-8"));
+            secretBytes = md.digest();
+        }
+        catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("no such algorithm!");
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException(e);
+        }
+
+
+        String md5code = new BigInteger(1, secretBytes).toString(16);
+        int length = md5code.length();
+        for (int i = 0; i < 32 - length; i++) {
+            md5code = "0" + md5code;
+        }
+        return md5code;
+    }
+    //java sha256算法
+    public static String sha256Hex(String input) {
+        try {
+            // 创建一个MessageDigest实例,并指定使用SHA-256算法
+            MessageDigest digest = MessageDigest.getInstance("SHA-256");
+
+            // 将输入字符串转换为字节数组,并更新摘要
+            byte[] hash = digest.digest(input.getBytes(StandardCharsets.UTF_8));
+
+            // 将字节数组转换为十六进制字符串
+            StringBuilder hexString = new StringBuilder();
+            for (byte b : hash) {
+                String hex = Integer.toHexString(0xff & b);
+                if (hex.length() == 1) hexString.append('0');
+                hexString.append(hex);
+            }
+
+            return hexString.toString();
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static String genSign(HashMap<String, String> params, String signKey, Integer signMethod)
+    {
+        params.put("sign_key", signKey);
+        String result = "";
+        try {
+            List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(params.entrySet());
+            Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {
+                public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
+                    return (o1.getKey()).toString().compareTo(o2.getKey());
+                }
+            });
+            // 构造签名键值对的格式
+            for (Map.Entry<String, String> item : infoIds) {
+                if (item.getKey() != null || item.getKey() != "") {
+                    String key = item.getKey();
+                    String val = item.getValue().trim();
+                    if (result == "") {
+                        result += key + "=" + val;
+                    } else {
+                        result += "&" + key + "=" + val;
+                    }
+                }
+            }
+            //System.out.println(result);
+        } catch(Exception e) {
+            throw new RuntimeException("error");
+        }
+        if(signMethod == 1) {
+            return sha256Hex(result);
+        }
+        return md5(result);
+    }
+
+    public static void main (String[] args) throws java.lang.Exception {
+        long l = System.currentTimeMillis() / 1000;
+
+        HashMap<String, String> map = new HashMap<String, String>();
+        map.put("client_id", "3295ee5021a0dd6436d18f56e7c761c6");
+        map.put("client_secret", "fe5539d17722035cba70a2e6220c43a4");
+        map.put("grant_type", "client_credentials");
+        map.put("phone", "18857526310");
+        long currentTimeMillis = System.currentTimeMillis();
+        map.put("timestamp", currentTimeMillis+"");
+
+        String signKey = "038bD3BAb4a25D84dc96";
+        Integer signMethod = 0;
+        String sign = genSign(map, signKey, signMethod);
+        System.out.println("sign:"+sign);
+        System.out.println("timestamp:"+currentTimeMillis);
+    }
+
 
 
 

+ 6 - 0
mjava-zhongche/src/main/java/com/malk/zhongche/controller/ZhongcheController.java

@@ -26,4 +26,10 @@ public class ZhongcheController {
     public McR updateTaskDelayInfo(@RequestBody Map map){
         return zhongcheService.updateTaskDelayInfo(map);
     }
+
+    //更新父任务任务类型
+    @PostMapping("/updateParentTaskType")
+    public McR updateParentTaskType(@RequestBody Map map){
+        return zhongcheService.updateParentTaskType(map);
+    }
 }

+ 4 - 0
mjava-zhongche/src/main/java/com/malk/zhongche/service/ZhongcheService.java

@@ -9,4 +9,8 @@ public interface ZhongcheService {
 
     McR updateTaskDelayInfo(Map map);
 
+    McR updateParentTaskType(Map map);
+
+    void updateLastTaskSfc();
+
 }

+ 159 - 0
mjava-zhongche/src/main/java/com/malk/zhongche/service/impl/ZhongcheServiceImpl.java

@@ -1,6 +1,8 @@
 package com.malk.zhongche.service.impl;
 
 import com.alibaba.fastjson.JSONObject;
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.algorithms.Algorithm;
 import com.malk.server.aliwork.YDConf;
 import com.malk.server.aliwork.YDParam;
 import com.malk.server.common.McR;
@@ -9,9 +11,12 @@ import com.malk.service.aliwork.YDClient;
 import com.malk.service.dingtalk.DDClient;
 import com.malk.service.dingtalk.DDClient_Contacts;
 import com.malk.service.teambition.TBClient;
+import com.malk.utils.UtilHttp;
 import com.malk.utils.UtilMap;
+import com.malk.utils.UtilToken;
 import com.malk.zhongche.service.ZhongcheService;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.logging.log4j.util.Strings;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -199,6 +204,90 @@ public class ZhongcheServiceImpl implements ZhongcheService {
         return McR.success();
     }
 
+    @Override
+    public McR updateParentTaskType(Map map) {
+        log.info("更新父任务任务类型:{}",JSONObject.toJSONString(map));
+        String taskId = UtilMap.getString(map, "taskId");
+
+        Map taskInfo = tbClient.queryTaskDetail(taskId, null, null).get(0);
+
+        String parentTaskId = UtilMap.getString(taskInfo, "parentTaskId");
+
+        Map parentTaskInfo = tbClient.queryTaskDetail(parentTaskId, null, null).get(0);
+
+        String projectId = UtilMap.getString(parentTaskInfo, "projectId");
+        String sfcId = UtilMap.getString(parentTaskInfo, "sfcId");
+
+        //获取项目任务类型
+        List<Map> result = searchProjectSfc(projectId);
+
+        String sfcId2 = "";//任务(企业)
+        String sfcId3 = "";//末级任务(企业)
+
+        for (Map resultMap : result) {
+            String name = UtilMap.getString(resultMap, "name");
+            String id = UtilMap.getString(resultMap, "id");
+
+            switch (name){
+                case "任务(企业)":sfcId2 = id;break;
+                case "末级任务(企业)":sfcId3 = id;break;
+                default:break;
+            }
+        }
+
+        //若父任务任务类型为末级任务(企业),更新为任务(企业)
+        if (sfcId.equals(sfcId3)){
+            updateTaskSfc(parentTaskId, sfcId2);
+        }
+
+        return McR.success();
+    }
+
+    @Override
+    public void updateLastTaskSfc() {
+        List<String> projectIds = searchProject();
+
+        for (String projectId : projectIds) {
+            if (!"69e1fcd4c41c37563c72888e".equals(projectId)) continue;
+
+            String sfcId = "";//末级任务(企业)
+            String sfcId2 = "";//任务(企业)
+
+            //获取项目任务类型
+            List<Map> result = searchProjectSfc(projectId);
+            for (Map resultMap : result) {
+                String name = UtilMap.getString(resultMap, "name");
+                String id = UtilMap.getString(resultMap, "id");
+
+                switch (name){
+                    case "任务(企业)":sfcId2 = id;break;
+                    case "末级任务(企业)":sfcId = id;break;
+                    default:break;
+                }
+            }
+
+            //查询项目下所有非顶级任务且任务类型为任务(企业)
+            List<Map> taskList = tbClient.queryProjectTaskList(projectId, UtilMap.map("q, pageSize", "taskLayer = exceptTopLevel AND scenarioId = " + sfcId2, 1000), null);
+
+            //遍历所有任务,查询末级任务
+            for (Map task : taskList) {
+                String taskId = UtilMap.getString(task, "id");
+
+                //查询该任务是否有子任务
+                List<Map> sonTaskList = tbClient.queryTaskDetail(null, null, taskId);
+
+                if (sonTaskList.isEmpty()){
+                    //更新任务类型为末级任务(企业)
+                    updateTaskSfc(taskId, sfcId);
+                }
+            }
+
+
+
+
+        }
+    }
+
     private Map getRootTask(String taskId) {
         Map taskInfo = tbClient.queryTaskDetail(taskId, null, null).get(0);
 
@@ -235,4 +324,74 @@ public class ZhongcheServiceImpl implements ZhongcheService {
         }
 
     }
+
+    private static final Long EXPIRES_IN = 7200000L;
+
+    private String getAccessToken() {
+            String accessToken = UtilToken.get("invalid-token-teambition");
+            if (StringUtils.isNotBlank(accessToken)) {
+                return accessToken;
+            } else {
+                Algorithm algorithm = Algorithm.HMAC256(tbConf.getAppSecret());
+                long timestamp = System.currentTimeMillis();
+                Date issuedAt = new Date(timestamp);
+                Date expiresAt = new Date(timestamp + EXPIRES_IN);
+                accessToken = JWT.create().withClaim("_appId", tbConf.getAppID()).withIssuedAt(issuedAt).withExpiresAt(expiresAt).sign(algorithm);
+                log.info("响应token, {}", accessToken);
+                UtilToken.put("invalid-token-teambition", accessToken, EXPIRES_IN);
+                return accessToken;
+            }
+
+    }
+
+    private Map<String, String> initHeaderToken() {
+        Map header = new HashMap();
+        header.put("Authorization", getAccessToken());
+        header.put("X-Tenant-Id", tbConf.getTenantId());
+        header.put("X-Tenant-Type", "organization");
+        return header;
+    }
+
+    // 操作者ID: 若是查询, 以操作人视角作为权限
+    private Map<String, String> initHeaderToken(String operatorId) {
+        Map header = initHeaderToken();
+        header.put("x-operator-id", operatorId);
+        return header;
+    }
+
+    //搜索项目任务类型
+    private List<Map> searchProjectSfc(String projectId) {
+        String s = UtilHttp.doGet("https://open.teambition.com/api/v3/project/" + projectId + "/scenariofieldconfig/search", initHeaderToken(), UtilMap.map("objectTypes", "task"));
+        Map result = (Map) JSONObject.parse(s);
+
+        log.info("result:{}",result);
+
+        List<Map> list = UtilMap.getList(result, "result");
+
+        return list;
+    }
+
+    //更新任务的任务类型
+    private Map updateTaskSfc(String taskId, String sfcId) {
+        String s = UtilHttp.doPut("https://open.teambition.com/api/v3/task/" + taskId + "/sfc/update", initHeaderToken(tbConf.getOperatorId()), null, UtilMap.map("sfcId", sfcId));
+
+        Map result = (Map) JSONObject.parse(s);
+
+        log.info("result:{}",result);
+
+        return result;
+    }
+
+    //通过TQL搜索项目
+    private List<String> searchProject() {
+        String s = UtilHttp.doGet("https://open.teambition.com/api/project/search", initHeaderToken(tbConf.getOperatorId()), UtilMap.map("pageSize", 100));
+
+        Map result = (Map) JSONObject.parse(s);
+
+        log.info("result:{}",result);
+
+        List<String> list = UtilMap.getList(result, "result");
+
+        return list;
+    }
 }

+ 19 - 0
mjava-zhongche/src/test/java/com/malk/zhongche/ZcTest.java

@@ -1,4 +1,23 @@
 package com.malk.zhongche;
 
+import com.malk.zhongche.service.ZhongcheService;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@Slf4j
+@SpringBootTest
+@RunWith(SpringRunner.class)
 public class ZcTest {
+    @Autowired
+    private ZhongcheService zhongcheService;
+
+    @Test
+    //刷新所有项目末级任务的任务类型
+    public void test(){
+        zhongcheService.updateLastTaskSfc();
+    }
 }