Sfoglia il codice sorgente

新增自动同步凭证插件

sbtjtserver/zhaoxh 7 mesi fa
parent
commit
cdfe8d1623
1 ha cambiato i file con 413 aggiunte e 0 eliminazioni
  1. 413 0
      src/main/java/fi/gl/task/AutoSynVoucher.java

+ 413 - 0
src/main/java/fi/gl/task/AutoSynVoucher.java

@@ -0,0 +1,413 @@
+package fi.gl.task;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import kd.bos.algo.DataSet;
+import kd.bos.algo.Row;
+import kd.bos.context.RequestContext;
+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.exception.KDException;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.schedule.executor.AbstractTask;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+import org.apache.commons.lang3.StringUtils;
+
+import java.sql.*;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.util.*;
+import java.util.Date;
+
+/**
+ * 自动同步凭证任务插件
+ * 2024-09-11 wangj
+ * 主要功能:自动同步每月凭证数据到用友中间表
+ */
+public class AutoSynVoucher extends AbstractTask {
+    protected static final Log log = LogFactory.getLog(AutoSynVoucher.class);
+    String DB_VOUCHER_FIELDS = "voucherno,yearv,periodv,orgcd,orgnm,prepareddatev,checkeddate,tallydate,datadt," +
+            "creditamount,debitamount,localcreditamount,localdebitamount,direction,explanation," +
+            "subjcd,subjnm,currcd,currnm";
+
+    String DB_BALANCE_FIELDS = "direction,yearv,periodv,subjcd,subjnm,currcd,currnm,orgcd,orgnm,datadt," +
+            "creditamount,debitamount,localcreditamount,localdebitamount";
+    String SELECTFIELDS = "billno,period,org,createtime,auditdate,bookeddate," +
+            "entries,entries.account,entries.creditori,entries.debitori,entries.creditlocal,entries.debitlocal,entries.entrydc,entries.edescription,entries.currency";
+
+    @Override
+    public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
+        Connection conn = null;
+        PreparedStatement pstmt1 = null;
+        Statement pstmt2 = null;
+        PreparedStatement pstmt3 = null;
+        try {
+            //连接数据库
+            conn = getConnect(); // 获取数据库连接
+            if(conn!=null){
+                conn.setAutoCommit(false); // 关闭自动提交
+                //缓存组织映射表Map
+                Map orgMap_numbber = new HashMap();
+                Map orgMap_name = new HashMap();
+                QFilter qFilter_enable = new QFilter("enable", QCP.equals,"1");
+                QFilter qFilter_status = new QFilter("status", QCP.equals, "C");
+                DynamicObject[] orgCol = BusinessDataServiceHelper.load(
+                        "nckd_gl_orgmapp","nckd_orgfield,nckd_yyorgnumber,nckd_yyorgname",new QFilter[]{qFilter_enable,qFilter_status});
+                for(DynamicObject orgObj : orgCol){
+                    DynamicObject kd_org = orgObj.getDynamicObject("nckd_orgfield");
+                    orgMap_numbber.put(kd_org.getString("id"),orgObj.getString("nckd_yyorgnumber"));
+                    orgMap_name.put(kd_org.getString("id"),orgObj.getString("nckd_yyorgname"));
+                }
+
+                //查找待同步数据执行插入数据
+                pstmt1 = conn.prepareStatement("INSERT INTO jf_voucher (" + DB_VOUCHER_FIELDS + ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
+                doExecuteNewData(conn,pstmt1,orgMap_numbber,orgMap_name);
+
+                //清空汇总中间表
+                pstmt2 = conn.createStatement();
+                String deleteSql = "DELETE FROM jf_balance";
+                int affectedRows = pstmt2.executeUpdate(deleteSql);
+                log.info("删除中间表记录数:"+affectedRows);
+                conn.commit();
+
+                //重新汇总数据插入汇总中间表
+                pstmt3 = conn.prepareStatement("INSERT INTO jf_balance (" + DB_BALANCE_FIELDS + ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
+                doExecuteTotalData(conn,pstmt3,orgMap_numbber,orgMap_name);
+            }else{
+                log.info("连接用友总账数据库失败");
+            }
+        } catch (Exception e) {
+            log.info("同步凭证到用友总账数据库失败:"+e.getMessage());
+            throw new RuntimeException(e);
+        } finally{
+            try {
+                if(pstmt1!=null){
+                    pstmt1.close();
+                }
+                if(pstmt2!=null){
+                    pstmt2.close();
+                }
+                if(conn!=null){
+                    conn.setAutoCommit(true); // 重新开启自动提交
+                    conn.close();
+                } 
+            }catch (SQLException e) {
+                log.info("释放数据库连接失败:"+e.getMessage());
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private void doExecuteTotalData(Connection conn, PreparedStatement pstmt3, Map orgMap_numbber, Map orgMap_name) throws SQLException {
+        //获取待同步数据
+        JSONArray voucherCol = getVoucherTotalDatas(orgMap_numbber,orgMap_name);
+        // 模拟大量插入操作
+        for (int i=0;i<voucherCol.size();i++) {
+            JSONObject voucherObj = voucherCol.getJSONObject(i);
+            doInsertTotalData(pstmt3,voucherObj);
+        }
+        // 处理剩余的数据
+        if(voucherCol.size()>0){
+            pstmt3.executeBatch();
+            conn.commit();
+            pstmt3.clearBatch();
+        }
+    }
+
+    private void doInsertTotalData(PreparedStatement pstmt3, JSONObject voucherObj) throws SQLException {
+        pstmt3.setString(1, voucherObj.getString("direction"));
+        pstmt3.setString(2, voucherObj.getString("yearv"));
+        pstmt3.setString(3, voucherObj.getString("periodv"));
+        pstmt3.setString(4, voucherObj.getString("subjcd"));
+        pstmt3.setString(5, voucherObj.getString("subjnm"));
+        pstmt3.setString(6, voucherObj.getString("currcd"));
+        pstmt3.setString(7, voucherObj.getString("currnm"));
+        pstmt3.setString(8, voucherObj.getString("orgcd"));
+        pstmt3.setString(9, voucherObj.getString("orgnm"));
+        pstmt3.setString(10, voucherObj.getString("datadt"));
+        pstmt3.setBigDecimal(11, voucherObj.getBigDecimal("creditamount"));
+        pstmt3.setBigDecimal(12, voucherObj.getBigDecimal("debitamount"));
+        pstmt3.setBigDecimal(13, voucherObj.getBigDecimal("localcreditamount"));
+        pstmt3.setBigDecimal(14, voucherObj.getBigDecimal("localdebitamount"));
+        pstmt3.addBatch();
+    }
+
+    /*
+    * 获取凭证汇总数据集
+     */
+    private JSONArray getVoucherTotalDatas(Map orgMapNumbber, Map orgMapName) {
+        String sql = "SELECT TEMP.orgid,TEMP.yearv,TEMP.periodv,TEMP.subjcd,TEMP.subjnm,TEMP.currentid,TEMP.entrydc," +
+                "SUM(TEMP.creditamount) creditamount_total,SUM(TEMP.debitamount) debitamount_total," +
+                "SUM(TEMP.localcreditamount) localcreditamount_total,SUM(TEMP.localdebitamount) localdebitamount_total " +
+                "FROM (" +
+                    "SELECT VOU.forgid orgid,BD.fperiodyear yearv,BD.fperiodnumber periodv," +
+                    "ACC.fnumber subjcd,ACC.fname subjnm ,VOUE.FCURRENCYID currentid,VOUE.FENTRYDC entrydc," +
+                    "ISNULL(VOUE.FORIGINALCREDIT,0)  creditamount,ISNULL(VOUE.FORIGINALDEBIT,0)  debitamount," +
+                    "ISNULL(VOUE.FLOCALCREDIT,0)  localcreditamount,ISNULL(VOUE.FLOCALDEBIT,0) localdebitamount " +
+                    "FROM T_GL_VOUCHER VOU " +
+                    "LEFT JOIN T_GL_VOUCHERENTRY VOUE ON VOU.FID = VOUE.FID " +
+                    "LEFT JOIN T_BD_period BD ON VOU.FPERIODID = BD.FID " +
+                    "LEFT JOIN T_BD_Account ACC ON VOUE.faccountid  = ACC.FID " +
+                    "WHERE VOU.fispost='1' " +
+//                    "AND VOU.fk_nckd_issynyy='1'\n" +
+                ") TEMP " +
+                "GROUP BY TEMP.orgid,TEMP.yearv,TEMP.periodv,TEMP.subjcd,TEMP.subjnm,TEMP.currentid,TEMP.direction";
+        DataSet ds = DB.queryDataSet(this.getClass().getName(), new DBRoute("fi"), sql, null);
+        JSONArray jsonArray = new JSONArray();
+        Map currentList = new HashMap();
+        for (Row row : ds) {
+            JSONObject jsonObj = new JSONObject();
+            String orgcd = orgMapNumbber.get(row.getString("orgid"))!=null?orgMapNumbber.get(row.getString("orgid")).toString():"";
+            jsonObj.put("orgcd",orgcd);
+            String orgnm = orgMapName.get(row.getString("orgid"))!=null?orgMapName.get(row.getString("orgid")).toString():"";
+            jsonObj.put("orgnm",orgnm);
+            jsonObj.put("yearv",row.getString("yearv"));
+            String periodv = tranPeriodv(row.getString("yearv"));
+            jsonObj.put("periodv",periodv);
+            jsonObj.put("subjcd",row.getString("subjcd"));
+            jsonObj.put("subjnm",row.getString("subjnm"));
+            if(row.getString("currentid")!=null && currentList.get(row.getString("currentid"))==null){
+                DynamicObject currentObj = BusinessDataServiceHelper.loadSingle(row.getString("currentid"),"bd_currency");
+                Map currentMap = new HashMap();
+                currentMap.put("number",currentObj.getString("number"));
+                currentMap.put("name",currentObj.getString("name"));
+                currentList.put(row.getString("currentid"),currentMap);
+                jsonObj.put("currcd",currentObj.getString("number"));
+                jsonObj.put("currnm",currentObj.getString("name"));
+            }else{
+                Map currentMap = (Map) currentList.get(row.getString("currentid"));
+                jsonObj.put("currcd",currentMap.get("number"));
+                jsonObj.put("currnm",currentMap.get("name"));
+            }
+            String direction = "";
+            if(!StringUtils.isEmpty(row.getString("entrydc"))){
+                String entrydc = row.getString("entrydc");
+                if("1".equals(entrydc)){//借方
+                    direction = "D";
+                }else if("-1".equals(entrydc)){//贷方
+                    direction = "C";
+                }
+            }
+            jsonObj.put("direction",direction);
+            jsonObj.put("creditamount",row.getString("creditamount_total"));
+            jsonObj.put("debitamount",row.getString("debitamount_total"));
+            jsonObj.put("localcreditamount",row.getString("localcreditamount_total"));
+            jsonObj.put("localdebitamount",row.getString("localdebitamount_total"));
+            jsonArray.add(jsonObj);
+        }
+        return jsonArray;
+    }
+
+    /*
+    * 转换期间字段补0
+     */
+    private String tranPeriodv(String yearv) {
+        String realyearv = "";
+        if(!yearv.contains("0")){
+            realyearv = "0" + yearv;
+        }else{
+            realyearv = yearv;
+        }
+        return realyearv;
+    }
+
+    /*
+    * 执行插入数据
+     */
+    private void doExecuteNewData(Connection conn, PreparedStatement pstmt, Map orgMap_numbber, Map orgMap_name) throws SQLException {
+        // 设置批处理大小
+        int batchSize = 500;
+        int count = 0;
+        //获取待同步数据
+        DynamicObject[] voucherCol = getVoucherDatas();
+        String ids = "";
+        //数据日期
+        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
+        String datadt = sdf1.format(new Date());
+        // 模拟大量插入操作
+        for (DynamicObject voucherObj : voucherCol) {
+            doInsertData(pstmt,voucherObj,orgMap_numbber,orgMap_name,datadt);
+            ids = ids + "," + voucherObj.getString("id");
+            if (++count % batchSize == 0) {
+                pstmt.executeBatch(); // 执行批处理
+                conn.commit(); // 可以在每个批次后提交事务
+                pstmt.clearBatch(); // 清空批处理
+                updateBillSign(ids); //更新凭证同步标识
+                ids = "";
+            }
+        }
+
+        // 处理剩余的数据
+        if (count % batchSize != 0) {
+            pstmt.executeBatch(); // 执行最后一个批次
+            conn.commit();
+            pstmt.clearBatch();
+            updateBillSign(ids);
+        }
+    }
+
+    private void updateBillSign(String ids) {
+        ids = ids.substring(1);
+        String sql = "UPDATE T_GL_VOUCHER SET fk_nckd_issynyy=0 WHERE FID IN ("+ids+")";
+        DB.update(DBRoute.of("fi"), sql);
+    }
+
+    private void doInsertData(PreparedStatement pstmt, DynamicObject voucherObj, Map orgMap_numbber, Map orgMap_name, String datadt)
+            throws SQLException {
+        /*------------------获取凭证单据头字段信息开始----------------*/
+        //凭证号
+        String billno = voucherObj.getString("billno");
+        //yearv会计年度
+        DynamicObject period = voucherObj.getDynamicObject("period");
+        String periodNumber = period.getString("number");
+        String yearv = periodNumber.substring(0,4);
+        //periodv会计期间
+        String periodv = periodNumber.substring(4,6);
+        //财务组织-映射表转换
+        DynamicObject org = voucherObj.getDynamicObject("org");
+        String orgcd = orgMap_numbber.get(org.getString("id"))!=null?
+                orgMap_numbber.get(org.getString("id")).toString():"";
+        String orgnm = orgMap_name.get(org.getString("id"))!=null?
+                orgMap_name.get(org.getString("id")).toString():"";
+        //制单日期
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        String prepareddatev = sdf.format(voucherObj.getDate("createtime"));
+        //审核日期
+        String checkeddate = sdf.format(voucherObj.getDate("auditdate"));
+        //记账日期
+        String tallydate = sdf.format(voucherObj.getDate("bookeddate"));
+
+        /*------------------获取凭证单据头字段信息结束----------------*/
+        DynamicObjectCollection entriesCol = voucherObj.getDynamicObjectCollection("entries");
+        for(DynamicObject entriesObj : entriesCol){
+            /*-------------拼接表头字段开始------------*/
+            //凭证号
+            pstmt.setString(1, billno);
+            //yearv会计年度
+            pstmt.setString(2, yearv);
+            //periodv会计期间
+            pstmt.setString(3, periodv);
+            //财务组织编码
+            pstmt.setString(4, orgcd);
+            //财务组织名称
+            pstmt.setString(5, orgnm);
+            //制单日期
+            pstmt.setString(6, prepareddatev);
+            //审核日期
+            pstmt.setString(7, checkeddate);
+            //记账日期
+            pstmt.setString(8, tallydate);
+            //数据日期
+            pstmt.setString(9, datadt);
+            /*-------------拼接表头字段结束------------*/
+
+            /*-------------拼接分录字段开始------------*/
+            //原币贷方
+            double creditori = 0.00;
+            if(!StringUtils.isEmpty(entriesObj.getString("creditori"))){
+                creditori = entriesObj.getBigDecimal("creditori").doubleValue();
+            }
+            pstmt.setDouble(10, creditori);
+            //原币借方
+            double debitori = 0.00;
+            if(!StringUtils.isEmpty(entriesObj.getString("debitori"))){
+                debitori = entriesObj.getBigDecimal("debitori").doubleValue();
+            }
+            pstmt.setDouble(11, debitori);
+            //贷方
+            double creditlocal = 0.00;
+            if(!StringUtils.isEmpty(entriesObj.getString("creditlocal"))){
+                creditlocal = entriesObj.getBigDecimal("creditlocal").doubleValue();
+            }
+            pstmt.setDouble(12, creditlocal);
+            //借方
+            double debitlocal = 0.00;
+            if(!StringUtils.isEmpty(entriesObj.getString("debitlocal"))){
+                debitlocal = entriesObj.getBigDecimal("debitlocal").doubleValue();
+            }
+            pstmt.setDouble(13, debitlocal);
+            //方向
+            String direction = "";
+            if(!StringUtils.isEmpty(entriesObj.getString("entrydc"))){
+                String entrydc = entriesObj.getString("entrydc");
+                if("1".equals(entrydc)){//借方
+                    direction = "D";
+                }else if("-1".equals(entrydc)){//贷方
+                    direction = "C";
+                }
+            }
+            pstmt.setString(14, direction);
+            //摘要
+            pstmt.setString(15, entriesObj.getString("edescription"));
+            //会计科目编码
+            DynamicObject account = entriesObj.getDynamicObject("account");
+            String subjcd = "";
+            String subjnm = "";
+            if(account!=null){
+                subjcd = account.getString("number");
+                subjnm = account.getString("name");
+            }
+            pstmt.setString(16,subjcd);
+            //会计科目名称
+            pstmt.setString(17,subjnm);
+            //币种编码
+            DynamicObject currency = entriesObj.getDynamicObject("currency");
+            String currcd = "";
+            String currnm = "";
+            if(currency!=null){
+                currcd = currency.getString("number");
+                currnm = currency.getString("name");
+            }
+            pstmt.setString(18,currcd);
+            //币种名称
+            pstmt.setString(19,currnm);
+            /*-------------拼接分录字段结束------------*/
+            pstmt.addBatch();
+        }
+    }
+
+    private DynamicObject[] getVoucherDatas() {
+        Date beginDate = getBeginDate();
+        QFilter qFilter_beginDate = new QFilter("",QCP.large_equals,beginDate);
+        QFilter qFilter_ispost = new QFilter("ispost", QCP.equals,"1");
+        DynamicObject[] voucherCol = BusinessDataServiceHelper.load(
+                "gl_voucher",SELECTFIELDS,new QFilter[]{qFilter_ispost,qFilter_beginDate});
+        return voucherCol;
+    }
+
+    private Date getBeginDate() {
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+        Calendar cal_1=Calendar.getInstance();//获取当前日期
+        LocalDate today = LocalDate.now(); // 获取当前日期
+        LocalDate firstDayOfMonth = today.withDayOfMonth(1); // 获取当前月的第一天
+        if (today.equals(firstDayOfMonth)) {
+            cal_1.add(Calendar.MONTH, -1);
+        }
+        cal_1.set(Calendar.DAY_OF_MONTH,1);//设置为1号,当前日期既为本月第一天
+        Date firstDay = cal_1.getTime();
+        return firstDay;
+    }
+
+    private Connection getConnect() throws ClassNotFoundException, SQLException {
+        //1.获取接口链接等信息
+        DynamicObject jkpzxx = BusinessDataServiceHelper.loadSingle("nckd_jkpzxx",
+                new QFilter[]{new QFilter("number","=","synvoucher")});
+        String servername =  jkpzxx.getString("nckd_servername");
+        String port =  jkpzxx.getString("nckd_port");
+        String username = jkpzxx.getString("nckd_user");
+        String password = jkpzxx.getString("nckd_password");
+        String jdbcUrl = "jdbc:oracle:thin:@"+servername+":"+port+"/service";
+        // 加载Oracle JDBC驱动
+        Class.forName("oracle.jdbc.driver.OracleDriver");
+        // 建立连接
+        Connection conn = DriverManager.getConnection(jdbcUrl, username, password);
+
+        return conn;
+    }
+}