From 2a9141bf2ccc1fb386f4bfe7ebaa2a260fcd38bc Mon Sep 17 00:00:00 2001 From: yuxueliang0813 <407010292@qq.com> Date: Tue, 24 Sep 2024 21:16:46 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=A8=E5=8F=8B=E6=8E=A5=E5=8F=A3=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E6=97=A5=E5=BF=97=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../recon/opplugin/YongyouBIPOperation.java | 127 +++++++++++++----- .../shkd/repc/task/DobeDWaccountTask.java | 92 ++++++------- .../src/main/java/shkd/utils/DobeDWUtils.java | 5 + 3 files changed, 138 insertions(+), 86 deletions(-) diff --git a/fi/fi/shkd-fi-fi-plugin/src/main/java/shkd/repc/recon/opplugin/YongyouBIPOperation.java b/fi/fi/shkd-fi-fi-plugin/src/main/java/shkd/repc/recon/opplugin/YongyouBIPOperation.java index 42e4c3b..d9b54bd 100644 --- a/fi/fi/shkd-fi-fi-plugin/src/main/java/shkd/repc/recon/opplugin/YongyouBIPOperation.java +++ b/fi/fi/shkd-fi-fi-plugin/src/main/java/shkd/repc/recon/opplugin/YongyouBIPOperation.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import kd.bos.dataentity.entity.DynamicObject; +import kd.bos.dataentity.entity.DynamicObjectCollection; import kd.bos.db.DB; import kd.bos.db.DBRoute; import kd.bos.entity.plugin.AbstractOperationServicePlugIn; @@ -18,7 +19,6 @@ import kd.sdk.plugin.Plugin; import nccloud.open.api.auto.token.cur.utils.APICurUtils; import okhttp3.*; import shkd.utils.DobeDWUtils; - import java.math.BigDecimal; @@ -92,11 +92,12 @@ public class YongyouBIPOperation extends AbstractOperationServicePlugIn implemen public void afterExecuteOperationTransaction(AfterOperationArgs e) { super.afterExecuteOperationTransaction(e); //audit审核通过后,判断当前是合同付款申请单还是无文本合同 - if("save".equals(e.getOperationKey())){ + if("syncbip".equals(e.getOperationKey())){ DynamicObject[] dos = e.getDataEntities(); DynamicObject payrequestinfo = null; for (int i = 0; i < dos.length; i++) { payrequestinfo = dos[i]; + if("recon_payreqbill".equals(payrequestinfo.getDataEntityType().getName())){ //判断实体名称为合同付款申请单 handleForBIP(e.getOperationKey(),payrequestinfo,false); @@ -143,23 +144,20 @@ public class YongyouBIPOperation extends AbstractOperationServicePlugIn implemen payData.put("billdate",DobeDWUtils.getDateString(payrequestinfo.getDate("bizdate")));//业务日期,YYYY-MM-DD String ap_recaccount = null;//收款银行账户编码 //无文本合同的个人垫付时,是业务员 -// boolean isgrdf = isnotext && payrequestinfo.getBoolean("grdf"); - boolean isgrdf = isnotext && false; + boolean isgrdf = isnotext && payrequestinfo.getBoolean("qeug_grdf"); if(isgrdf){ payData.put("objtype","3");//往来对象(0-客户 1-供应商 2-部门 3-业务员) - ap_recaccount = ""; + ap_recaccount = payrequestinfo.getDynamicObject("qeug_personbank").getString("qeug_banknumber"); + payData.put("pk_psndoc",payrequestinfo.getDynamicObject("qeug_personbank").getString("number"));//业务员编码 人员工号 个人业务的时候,3-业务员 必传 }else{ payData.put("objtype","0");//往来对象(0-客户 1-供应商 2-部门 3-业务员) ap_recaccount = payrequestinfo.getString("receiveno"); - } - String supplierNum = payrequestinfo.getDynamicObject("receiveunit").getString("number"); - payData.put("customer",supplierNum);//客户编码 即使是供应商也传入到该字段 - payData.put("pk_dept",companyDept[1]);//部门编码(通过公司主体明细表找部门编码) - if(isgrdf){ - payData.put("pk_psndoc","");//业务员编码 人员工号 个人业务的时候,3-业务员 必传 - }else{ payData.put("pk_psndoc","");//非个人业务 不传 } + String supplierNum = payrequestinfo.getDynamicObject("receiveunit").getString("number"); + long supplierid = payrequestinfo.getDynamicObject("receiveunit").getLong("id"); + payData.put("customer",supplierNum);//客户编码 即使是供应商也传入到该字段 + payData.put("pk_dept",companyDept[1]);//部门编码(通过公司主体明细表找部门编码) payData.put("pk_currtype","CNY");//币种,传编码CNY payData.put("pk_busitype","AP04");//业务流程,传编码 AP01(生产可能有变化) @@ -178,15 +176,16 @@ public class YongyouBIPOperation extends AbstractOperationServicePlugIn implemen payData.put("globallocal",bcsqje.toString());//全局本币金额 含税金额,xxxxx.00000000 payData.put("pu_org",companyDept[0]);//业务组织编码 转换成对应财务公司的编码 - payData.put("pu_deptid",companyDept[1]);//业务部门编码 转换成对应财务部门的编码 +// payData.put("pu_deptid",companyDept[1]);//业务部门编码 转换成对应财务部门的编码 // payData.put("pu_psndoc","");//业务人员编码 业务人员和制单人是否同一个?先注释 - String creator = payrequestinfo.getDynamicObject("handler").getString("number"); - payData.put("billmaker",creator);//制单人编码 制单人工号 +// String creator = payrequestinfo.getDynamicObject("handler").getString("number"); + payData.put("billmaker",DobeDWUtils.clientid);//制单人编码 固定传ISC payData.put("billstatus","1");//默认1 审批通过 payData.put("approvestatus","1");//默认1 审批通过 // String auditor = payrequestinfo.getDynamicObject("auditor").getString("number"); // payData.put("approver",auditor);//审核人编码 审核人工号 + payData.put("approver",DobeDWUtils.clientid);//审核人编码 固定传ISC payData.put("approvedate",DobeDWUtils.getDateString(payrequestinfo.getDate("auditDate")));//审核日期 YYYY-MM-DD // payData.put("src_syscode","ISC");//单据来源系统编码 非必传 if(isnotext){ @@ -205,18 +204,15 @@ public class YongyouBIPOperation extends AbstractOperationServicePlugIn implemen if(isgrdf){ items.put("objtype","3");//往来对象(0-客户 1-供应商 2-部门 3-业务员) + items.put("pk_psndoc",payrequestinfo.getDynamicObject("qeug_personbank").getString("number"));//业务员编码 人员工号 同表头 }else{ items.put("objtype","0");//往来对象(0-客户 1-供应商 2-部门 3-业务员) + items.put("pk_psndoc","");//非个人业务 不传 } items.put("customer",supplierNum);//客户编码 供应商的数据也传入这里 items.put("pk_dept",companyDept[1]);//部门编码(通过公司主体明细表找部门编码) - if(isgrdf){ - items.put("pk_psndoc","");//业务员编码 人员工号 同表头 - }else{ - items.put("pk_psndoc","");//非个人业务 不传 - } - items.put("pk_recpaytype","001");//付款业务类型,传编码例:001-货款 + items.put("pk_recpaytype","货款");//付款业务类型,传编码例:001-货款 items.put("prepay","0");//付款性质(0=应付款;1=预付款;) items.put("pk_currtype","CNY");//币种,传编码CNY items.put("money_de",bcsqje.toString());//贷方原币金额 含税金额,xxxxx.00000000 @@ -228,20 +224,41 @@ public class YongyouBIPOperation extends AbstractOperationServicePlugIn implemen items.put("globaldebit",bcsqje.toString());//全局本币金额 含税金额,xxxxx.00000000 items.put("taxcodeid","");//税码编码 应该不用传;联调再看; - BigDecimal rate = payrequestinfo.getBigDecimal("taxrate"); - if(rate == null){ - items.put("taxrate","0");//税率 - items.put("local_tax_de","0");//税额 + if(isnotext){ + //费用登记单的处理方式 + BigDecimal rate = payrequestinfo.getBigDecimal("taxrate");//税率 + if(rate == null){ + items.put("taxrate","0");//税率 + items.put("local_tax_de","0");//税额 + }else{ + items.put("taxrate",rate.toString());//税率 + items.put("local_tax_de",payrequestinfo.getBigDecimal("tax").toString());//税额 + } + items.put("notax_de",payrequestinfo.getBigDecimal("notaxamt").toString());//贷方无税金额,除税金额 }else{ - items.put("taxrate",rate.toString());//税率 - items.put("local_tax_de",payrequestinfo.getBigDecimal("tax").toString());//税额 + //付款申请单的处理方式 + BigDecimal invoicetax = payrequestinfo.getBigDecimal("invoicetax");//发票的税额 + if(invoicetax == null || invoicetax.compareTo(BigDecimal.ZERO) == 0){ + items.put("taxrate","0");//税率 + items.put("local_tax_de","0");//税额 + items.put("notax_de",bcsqje.toString());//贷方无税金额,除税金额 + }else{ + items.put("taxrate",invoicetax.divide(bcsqje.subtract(invoicetax)).multiply(BigDecimal.valueOf(100)));//税率=税额/不含税 * 100 + items.put("local_tax_de",invoicetax.toString());//税额 + items.put("notax_de",bcsqje.subtract(invoicetax).toString());//贷方无税金额,除税金额 + } } - items.put("notax_de",payrequestinfo.getBigDecimal("notaxamt").toString());//贷方无税金额,除税金额 items.put("pu_org",companyDept[0]);//业务组织编码 同表头公司编码 - items.put("pu_deptid",companyDept[1]);//业务部门编码 费用承担部门编码,转换成财务组织编码 - - items.put("pk_subjcode","");//收支项目编码 费用项目,例:660224-管理费用-服务费 会计科目(一个) +// items.put("pu_deptid",companyDept[1]);//业务部门编码 费用承担部门编码,转换成财务组织编码 + //外部公司:22020104\应付账款\往来单位\外部单位(工程类) + //内部关联公司:22020105\应付账款\往来单位\内部单位(关联方) + String suptype = getSupplierType(supplierid); + if("DB01".equals(suptype)){ + items.put("pk_subjcode","22020105");//集团内 + }else{ + items.put("pk_subjcode","22020104");//收支项目编码 费用项目,例:660224-管理费用-服务费 会计科目(一个) + } items.put("ap_payaccount",ap_payaccount);//付款银行账户编码 同表头 items.put("ap_recaccount",ap_recaccount);//收款银行账户编码 items.put("pk_balatype","07");//结算方式编码,传编码例:07-网银 @@ -280,6 +297,7 @@ public class YongyouBIPOperation extends AbstractOperationServicePlugIn implemen log.error("用友认证接口返回的accessToken为空"); return; } + //处理合同付款申请单的审核推送用友bip,组装付款入参 JSONObject payData = zzPayData(eventName,payrequestinfo,isnotext); OkHttpClient client = new OkHttpClient(); @@ -293,36 +311,71 @@ public class YongyouBIPOperation extends AbstractOperationServicePlugIn implemen .header("client_id", DobeDWUtils.clientid) .build(); String yynum = null;//用友单据编号 + JSONObject json_reuslt = null; try { Response response = client.newCall(request).execute(); - JSONObject json_reuslt = JSON.parseObject(response.body().string()); + json_reuslt = JSON.parseObject(response.body().string()); if(!"true".equals(json_reuslt.getString("success"))){ - log.error(String.format("用友付款接口处理失败,具体原因:%s", json_reuslt.getString("message"))); - //此时除了日志打印,还需要补偿机制,应该加入MQ走后续定时触发? + log.error(String.format("用友付款接口处理失败,具体原因:%s", json_reuslt.toString())); + //此时除了日志打印,增加日志记录 + DobeDWUtils.saveLog(payrequestinfo.getString("billno"),"用友BIP",payData.toString(),json_reuslt.toString(),false); }else{ yynum = json_reuslt.getJSONObject("data").getString("billno"); } } catch (Exception e) { log.error(String.format("用友付款接口异常:%s", e.getMessage())); - throw new RuntimeException(e); +// throw new RuntimeException(e); + DobeDWUtils.saveLog(payrequestinfo.getString("billno"),"用友BIP",payData.toString(),e.getMessage(),false); } if(DobeDWUtils.isEmpty(yynum)){ log.error("用友付款接口返回的billno为空"); + DobeDWUtils.saveLog(payrequestinfo.getString("billno"),"用友BIP",payData.toString(),"用友billno为空"+json_reuslt.toString(),false); }else{ //推送用友bip成功后,反写合同付款申请单的用友付款单id字段值 - String sql = "UPDATE t_xxx SET field=? WHERE fid=?;"; + String sql = "UPDATE t_xxx SET fk_qeug_yynum=? WHERE fid=?;"; DB.update(DBRoute.of("scm"), sql, new Object[]{yynum, payrequestinfo.getLong("id")}); } + DobeDWUtils.saveLog(payrequestinfo.getString("billno"),"用友BIP",payData.toString(),json_reuslt.toString(),true); } private void handleWithOutContract(String eventName, DynamicObject payrequestinfo){ //处理无文本合同的审核推送用友bip String yyid = null;//用友单据id //推送用友bip成功后,反写无文本合同的用友付款单id字段值 - String sql = "UPDATE t_recon_connotextbill SET fyyid=? WHERE fid=?;"; + String sql = "UPDATE t_recon_connotextbill SET fk_qeug_yynum=? WHERE fid=?;"; DB.update(DBRoute.of("scm"), sql, new Object[]{yyid, payrequestinfo.getLong("id")}); } + private String getSupplierType(long supplierid){ + //根据供应商id从供应商F7中得到供应商的分类标准 + DynamicObject supinfo = BusinessDataServiceHelper.loadSingle("resm_supplier_f7",new QFilter[]{new QFilter("id","=",supplierid)}); + DynamicObjectCollection orgcolls = supinfo.getDynamicObjectCollection("entry_org");//供应商所属组织,只查找集团的 + DynamicObject orginfo = null; + DynamicObjectCollection typecolls = null;//供应商所属组织下的供应商分类分录 + DynamicObject typeinfo = null; + String supTypeStr = null; + for (int i = 0; i < orgcolls.size(); i++) { + orginfo = orgcolls.get(i); + if(orginfo.getDynamicObject("belongorg") != null && "dobe".equalsIgnoreCase(orginfo.getDynamicObject("belongorg").getString("number"))){ + typecolls = orginfo.getDynamicObjectCollection("entry_org_group");//供应商所属组织下的供应商分类分录 + for (int j = 0; j < typecolls.size(); j++) { + typeinfo = typecolls.get(j); + if(typeinfo.getDynamicObject("suppliergroup") != null){ + supTypeStr = typeinfo.getDynamicObject("suppliergroup").getString("number"); + if("DB01".equals(supTypeStr) || "DB02".equals(supTypeStr)){ + break; + } + } + } + } + } + + if(supTypeStr == null){ + supTypeStr = "DB02";//如果上述未找到对应分类,则默认算集团外 + } + return supTypeStr; + } + private RequestBody createFormRequestBody(JSONObject json_body) { // return RequestBody.create(ByteString.encodeUtf8(json_body.toJSONString()), DobeDWUtils.MTJSON); return RequestBody.create(json_body.toJSONString(), DobeDWUtils.MTJSON); diff --git a/fi/fi/shkd-fi-fi-plugin/src/main/java/shkd/repc/task/DobeDWaccountTask.java b/fi/fi/shkd-fi-fi-plugin/src/main/java/shkd/repc/task/DobeDWaccountTask.java index 9a41168..53c085d 100644 --- a/fi/fi/shkd-fi-fi-plugin/src/main/java/shkd/repc/task/DobeDWaccountTask.java +++ b/fi/fi/shkd-fi-fi-plugin/src/main/java/shkd/repc/task/DobeDWaccountTask.java @@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import kd.bos.context.RequestContext; import kd.bos.dataentity.entity.DynamicObject; +import kd.bos.dataentity.entity.DynamicObjectCollection; import kd.bos.exception.KDException; import kd.bos.logging.Log; import kd.bos.logging.LogFactory; @@ -20,6 +21,7 @@ import okhttp3.Response; import shkd.utils.DobeDWUtils; import java.io.IOException; +import java.util.HashMap; import java.util.Map; /** @@ -64,13 +66,10 @@ public class DobeDWaccountTask extends AbstractTask implements Plugin { } //根据项目查找成本科目的表头信息 DynamicObject billinfo = BusinessDataServiceHelper.loadSingle(entityName,new QFilter[]{new QFilter("project","=",projectinfo.getLong("id"))}); - boolean isNew = false; if(billinfo == null){ - isNew = true; billinfo = BusinessDataServiceHelper.newDynamicObject(entityName); + billinfo.set("project",projectinfo.getLong("id")); } - QFilter billfilter = new QFilter("fid","=", billinfo.getLong("id")); - JSONArray detailsJson = json_body.getJSONArray("data"); String acctid = null; String number = null; String name = null; @@ -81,7 +80,16 @@ public class DobeDWaccountTask extends AbstractTask implements Plugin { String taxrate = null; String isleaf = null; String level = null; + String parentid = null; DynamicObject acctinfo = null; + Map parentAccts = new HashMap<>();//现有科目集合 + JSONArray detailsJson = json_body.getJSONArray("data"); + DynamicObjectCollection doDetails = billinfo.getDynamicObjectCollection("costaccountentry"); + for (int i = 0; i < doDetails.size(); i++) { + acctinfo = doDetails.get(i); + parentAccts.put(acctinfo.getString("caentry_srcid"),acctinfo); + } + //循环入参,判断哪些科目该修改,哪些该新增 for (int i = 0; i < detailsJson.size(); i++) { json_body = detailsJson.getJSONObject(i); acctid = json_body.getString("accid");//科目id @@ -94,61 +102,47 @@ public class DobeDWaccountTask extends AbstractTask implements Plugin { taxrate = json_body.getString("taxrate");//税率 isleaf = json_body.getString("isleaf");//是否叶子节点 level = json_body.getString("level");//科目级次 + parentid = json_body.getString("parentid");//科目级次 if(DobeDWUtils.isEmpty(number) || DobeDWUtils.isEmpty(name) || DobeDWUtils.isEmpty(isleaf) || DobeDWUtils.isEmpty(level) || DobeDWUtils.isEmpty(acctid)){ //如果组织ID和组织编码 名称是空的,则跳过此记录 log.info(String.format("成本科目入参为空异常:%s", json_body.toJSONString())); continue; + }else if(Integer.parseInt(level) >= 2 && DobeDWUtils.isEmpty(parentid)){ + log.info(String.format("成本科目级次大于等于2但是无对应的父级科目ID:%s", json_body.toJSONString())); + continue; } - //整体是修改的情况下,根据科目id查找是否已存在 - if(isNew){ - acctinfo = BusinessDataServiceHelper.newDynamicObject(accEntity); + //先从现有科目集合中获取,未获取到则新增 + acctinfo = parentAccts.get(acctid); + if(acctinfo == null){ + acctinfo = doDetails.addNew(); acctinfo.set("caentry_srcid", acctid);//源ID 用于存储数仓的科目id - acctinfo.set("caentry_number", number); - acctinfo.set("caentry_name", name); - acctinfo.set("caentry_longnumber", longnumber); - acctinfo.set("caentry_ciaccountflag", ciaccountflag);//科目类别 建安 1 非建安 0 - acctinfo.set("caentry_apportionway", null);//分摊方式 基础资料 - acctinfo.set("caentry_fullname", longname); - acctinfo.set("caentry_taxrate", taxrate); - acctinfo.set("caentry_isleaf", isleaf); - acctinfo.set("caentry_level", level); acctinfo.set("caentry_project", projectinfo.getLong("id"));//项目 acctinfo.set("caentry_enable", true);//默认 启用 - billinfo.getDynamicObjectCollection("costaccountentry").add(acctinfo); - }else{ - acctinfo = BusinessDataServiceHelper.loadSingle(accEntity,new QFilter[]{billfilter.and(new QFilter("caentry_srcid","=",acctid))}); - if(acctinfo == null){ - //不存在,做新增 根据实体名称创建动态对象 - acctinfo = BusinessDataServiceHelper.newDynamicObject(accEntity); - acctinfo.set("caentry_srcid", acctid);//源ID 用于存储数仓的科目id - acctinfo.set("caentry_number", number); - acctinfo.set("caentry_name", name); - acctinfo.set("caentry_longnumber", longnumber); - acctinfo.set("caentry_ciaccountflag", ciaccountflag);//科目类别 建安1 非建安0 - acctinfo.set("caentry_apportionway", null);//分摊方式 基础资料 - acctinfo.set("caentry_fullname", longname); - acctinfo.set("caentry_taxrate", taxrate); - acctinfo.set("caentry_isleaf", isleaf); - acctinfo.set("caentry_level", level); - acctinfo.set("caentry_project", projectinfo.getLong("id"));//项目 - acctinfo.set("caentry_enable", true);//默认 启用 -// acctinfo.set("caentry_isimportaccount", true);//是否导入科目 -// SaveServiceHelper.save(new DynamicObject[]{acctinfo}); - billinfo.getDynamicObjectCollection("costaccountentry").add(acctinfo); - }else{ - //已存在,做更新 编号、名称、长编号、名称、科目类别等 - acctinfo.set("caentry_number", number); - acctinfo.set("caentry_name", name); - acctinfo.set("caentry_longnumber", longnumber); - acctinfo.set("caentry_fullname", longname); - acctinfo.set("caentry_taxrate", taxrate); - acctinfo.set("caentry_isleaf", isleaf); - acctinfo.set("caentry_level", level); -// SaveServiceHelper.update(acctinfo); - } + //将此次新增的科目放到现有科目集合中,方便后续科目能获取到父级科目 + parentAccts.put(acctid,acctinfo); + } + //已存在,做更新 编号、名称、长编号、名称、科目类别等 + acctinfo.set("caentry_number", number); + acctinfo.set("caentry_name", name); + acctinfo.set("caentry_ciaccountflag", ciaccountflag);//科目类别 建安 1 非建安 0 + acctinfo.set("caentry_apportionway", null);//分摊方式 基础资料 + acctinfo.set("caentry_longnumber", longnumber); + acctinfo.set("caentry_fullname", longname); + acctinfo.set("caentry_taxrate", taxrate); + acctinfo.set("caentry_isleaf", isleaf); + acctinfo.set("caentry_level", level); + //创建组织 caentry_createorg + //组织 caentry_org + //业务组织 caentry_useorg + //处理父级科目 + if(parentAccts.get(parentid) != null){ + acctinfo.set("pid", parentAccts.get(parentid).getLong("id"));//设置父级科目 + //如果数仓不指定长编码和长名称,则需要在此处手动处理 + acctinfo.set("caentry_longnumber", parentAccts.get(parentid).getString("caentry_longnumber")+"."+number); + acctinfo.set("caentry_fullname", parentAccts.get(parentid).getString("caentry_fullname")+"_"+name); } } -// SaveServiceHelper.save(new DynamicObject[]{billinfo}); + SaveServiceHelper.save(new DynamicObject[]{billinfo}); } } \ No newline at end of file diff --git a/fi/fi/shkd-fi-fi-plugin/src/main/java/shkd/utils/DobeDWUtils.java b/fi/fi/shkd-fi-fi-plugin/src/main/java/shkd/utils/DobeDWUtils.java index 28b479c..c873825 100644 --- a/fi/fi/shkd-fi-fi-plugin/src/main/java/shkd/utils/DobeDWUtils.java +++ b/fi/fi/shkd-fi-fi-plugin/src/main/java/shkd/utils/DobeDWUtils.java @@ -40,6 +40,11 @@ public class DobeDWUtils { return value == null || value.trim().length() <= 0; } + public static void saveLog(String billno,String jkname,String inputs,String outputs,boolean isSuccess){ + //保存星瀚与第三方接口调用之间的日志记录 + //参数说明:单据编号、接口名称、接口入参、接口返回值、接口调用是否成功 + } + public static String getDateString(Date billDate){ //创建一个SimpleDateFormat对象,定义目标日期格式 SimpleDateFormat targetFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");