Browse Source

佣金周期和佣金调整

zhangyao 2 months ago
parent
commit
47b5ffef01

+ 18 - 0
com.awspaas.user.apps.donenow_ctt/src/com/awspaas/user/apps/donenow_ctt/controller/commissionController.java

@@ -0,0 +1,18 @@
+package com.awspaas.user.apps.donenow_ctt.controller;
+
+import com.actionsoft.bpms.commons.mvc.view.ResponseObject;
+import com.actionsoft.bpms.server.UserContext;
+import com.actionsoft.bpms.server.bind.annotation.Controller;
+import com.actionsoft.bpms.server.bind.annotation.Mapping;
+
+@Controller
+public class commissionController {
+    @Mapping(value = "com.awspaas.user.apps.donenow_ctt.commission_create_period")
+    public ResponseObject createPeriod(UserContext uc, String commissionBindid) {
+
+
+        return ResponseObject.newOkResponse();
+    }
+
+
+}

+ 29 - 14
com.awspaas.user.apps.donenow_ctt/src/com/awspaas/user/apps/donenow_ctt/cttConstant.java

@@ -28,7 +28,6 @@ public class cttConstant {
     public static final String CONTRACT_TYPE_PER_TICKET = "1204";
 
 
-
     /**
      * 一次性收费
      */
@@ -81,24 +80,40 @@ public class cttConstant {
      */
     public static final String CONTRACT_SERVICE_STATUS_APPROVE_REJECT = "4466";
 
-    public static final int  APPROVE_CHARGES = 84;             //成本审批
+    public static final int APPROVE_CHARGES = 84;             //成本审批
     public static final int APPROVE_MILESTONES = 85;            //里程碑审批
     public static final int APPROVE_SUBSCRIPTIONS = 86;           //订阅审批
-    public static final int  APPROVE_RECURRING_SERVICES = 87;    //定期服务审批
+    public static final int APPROVE_RECURRING_SERVICES = 87;    //定期服务审批
 
 
+    public static final int ACCOUNT_DEDUCTION_TYPE_LABOUR = 1318;  // 工时
+    public static final int ACCOUNT_DEDUCTION_TYPE_LABOUR_AJUST = 1319;//工时调整
+    public static final int ACCOUNT_DEDUCTION_TYPE_PREPAID_TIME_SELF_BILLING = 1320;//预付时间自身计费
+    public static final int ACCOUNT_DEDUCTION_TYPE_CHARGE = 1321;//成本
+    public static final int ACCOUNT_DEDUCTION_TYPE_EXPENSES = 1322;//费用
+    public static final int ACCOUNT_DEDUCTION_TYPE_MILESTONES = 1323;//里程碑
+    public static final int ACCOUNT_DEDUCTION_TYPE_SUBSCRIPTIONS = 1324;//订阅
+    public static final int ACCOUNT_DEDUCTION_TYPE_SERVICE = 1325;//服务
+    public static final int ACCOUNT_DEDUCTION_TYPE_SERVICE_AJUST = 1326;//服务调整
+    public static final int ACCOUNT_DEDUCTION_TYPE_INITIAL_COST = 1327;//初始费用
 
-    public static final int  ACCOUNT_DEDUCTION_TYPE_LABOUR = 1318;  // 工时
-    public static final int  ACCOUNT_DEDUCTION_TYPE_LABOUR_AJUST = 1319;//工时调整
-    public static final int  ACCOUNT_DEDUCTION_TYPE_PREPAID_TIME_SELF_BILLING = 1320;//预付时间自身计费
-    public static final int  ACCOUNT_DEDUCTION_TYPE_CHARGE = 1321;//成本
-    public static final int  ACCOUNT_DEDUCTION_TYPE_EXPENSES = 1322;//费用
-    public static final int  ACCOUNT_DEDUCTION_TYPE_MILESTONES = 1323;//里程碑
-    public static final int  ACCOUNT_DEDUCTION_TYPE_SUBSCRIPTIONS = 1324;//订阅
-    public static final int  ACCOUNT_DEDUCTION_TYPE_SERVICE = 1325;//服务
-    public static final int  ACCOUNT_DEDUCTION_TYPE_SERVICE_AJUST = 1326;//服务调整
-    public static final int  ACCOUNT_DEDUCTION_TYPE_INITIAL_COST = 1327;//初始费用
+    public static final int ACCOUNT_DEDUCTION_TYPE_COMMISSION = 1328;//佣金
 
-    public static final int  ACCOUNT_DEDUCTION_TYPE_COMMISSION = 1328;//佣金
+    /**
+     * 每月补贴
+     */
+    public static final String COMMISSION_RULE_MONTH = "4609";
+    /**
+     * 一次性补贴
+     */
+    public static final String COMMISSION_RULE_ONE_TIME = "4610";
+    /**
+     * 按年补贴
+     */
+    public static final String COMMISSION_RULE_YEAR = "4611";
+    /**
+     * 按季补贴
+     */
+    public static final String COMMISSION_RULE_QUARTER = "4612";
 
 }

+ 526 - 0
com.awspaas.user.apps.donenow_ctt/src/com/awspaas/user/apps/donenow_ctt/event/commissionFormAfterSave.java

@@ -0,0 +1,526 @@
+package com.awspaas.user.apps.donenow_ctt.event;
+
+import com.actionsoft.bpms.bo.engine.BO;
+import com.actionsoft.bpms.bpmn.engine.core.delegate.ProcessExecutionContext;
+import com.actionsoft.bpms.bpmn.engine.listener.ExecuteListener;
+import com.actionsoft.bpms.bpmn.engine.listener.ListenerConst;
+import com.actionsoft.bpms.server.UserContext;
+import com.actionsoft.bpms.util.DBSql;
+import com.actionsoft.exception.BPMNError;
+import com.actionsoft.sdk.local.SDK;
+import com.awspaas.user.apps.donenow_ctt.cttConstant;
+import org.apache.commons.lang3.StringUtils;
+
+import java.math.BigDecimal;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.time.LocalDate;
+import java.time.Month;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.TemporalAdjusters;
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.awspaas.user.apps.donenow_ctt.service.contractService.*;
+
+/**
+ * 佣金管理创建保存后事件
+ */
+public class commissionFormAfterSave extends ExecuteListener {
+
+    public String getDescription() {
+        return "佣金管理创建保存后事件,佣金调整后";
+    }
+
+    @Override
+    public void execute(ProcessExecutionContext processExecutionContext) throws Exception {
+        String bindid = processExecutionContext.getProcessInstance().getId();
+        String boName = processExecutionContext.getParameterOfString(ListenerConst.FORM_EVENT_PARAM_BONAME);
+        UserContext uc = processExecutionContext.getUserContext();
+
+        //佣金表单和佣金调整表单 保存时触发
+        if (boName.equals("BO_EU_DNCTT_COMMISSION") || boName.equals("BO_EU_DNCTT_COMMISSION_ADJUST")) {
+
+            BO commissionBO = processExecutionContext.getBO(boName);
+
+            String COMMISSION_BINDID = bindid;
+            if (boName.equals("BO_EU_DNCTT_COMMISSION_ADJUST"))
+                COMMISSION_BINDID = commissionBO.getString("COMMISSION_BINDID");
+
+            LocalDate PERIOD_BEGIN_DATE = getLocalDate(commissionBO.get("PERIOD_BEGIN_DATE"));//开始日期
+            final LocalDate PERIOD_BEGIN_DATE_final = getLocalDate(commissionBO.get("PERIOD_BEGIN_DATE"));//开始日期  不允许修改
+            LocalDate PERIOD_END_DATE = getLocalDate(commissionBO.get("PERIOD_END_DATE"));//结束日期
+            String RULE_CATE = commissionBO.getString("RULE_CATE");//佣金规则
+
+            //判断是否重建
+            boolean isRebuild = false;
+            //结束日期已修改
+            String PERIOD_END_DATE_Str = PERIOD_END_DATE.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+
+            if (boName.equals("BO_EU_DNCTT_COMMISSION")) {
+                //已审批 不允许修改 开始日期和佣金金额
+                String PERIOD_BEGIN_DATE_MIN = DBSql.getString("SELECT MIN(PERIOD_BEGIN_DATE) FROM BO_EU_DNCTT_COMMISSION_PERIOD WHERE BINDID = '" + bindid + "'");
+                String PERIOD_END_DATE_MAX = DBSql.getString("SELECT MAX(PERIOD_END_DATE) FROM BO_EU_DNCTT_COMMISSION_PERIOD WHERE BINDID = '" + bindid + "'");
+                if (StringUtils.isNotBlank(PERIOD_BEGIN_DATE_MIN) && !PERIOD_BEGIN_DATE.equals(getLocalDate(PERIOD_BEGIN_DATE_MIN))) {
+                    //开始日期已修改
+
+                    //已审批不允许修改
+                    if (DBSql.getInt("select count(1) CNT from BO_EU_DNCTT_COMMISSION_PERIOD where APPROVE_AND_POST_USER_ID IS NOT NULL AND LENGTH(APPROVE_AND_POST_USER_ID)>1 AND APPROVE_AND_POST_DATE IS NOT NULL AND  BINDID=?", new Object[]{bindid}) > 0) {
+                        throw new BPMNError("已审批不允许修改开始日期和佣金金额");
+                    }
+
+                    if (DBSql.getInt("select count(1) CNT from BO_EU_DNCTT_COMMISSION_PERIOD_AGENT where APPROVE_AND_POST_USER_ID IS NOT NULL AND LENGTH(APPROVE_AND_POST_USER_ID)>1 AND APPROVE_AND_POST_DATE IS NOT NULL AND  BINDID=?", new Object[]{bindid}) > 0) {
+                        throw new BPMNError("已审批不允许修改开始日期和佣金金额");
+                    }
+
+                    isRebuild = true;
+                }
+
+                if (StringUtils.isNotBlank(PERIOD_END_DATE_MAX) && !PERIOD_END_DATE.equals(getLocalDate(PERIOD_END_DATE_MAX))) {
+
+                    if (DBSql.getInt("select count(1) CNT from BO_EU_DNCTT_COMMISSION_PERIOD where APPROVE_AND_POST_USER_ID IS NOT NULL AND LENGTH(APPROVE_AND_POST_USER_ID)>1 AND APPROVE_AND_POST_DATE IS NOT NULL AND  BINDID=? AND PERIOD_END_DATE>=?", new Object[]{bindid, PERIOD_END_DATE_Str}) > 0) {
+                        throw new BPMNError("已审批不允许修改开始日期和佣金金额");
+                    }
+
+                    if (DBSql.getInt("select count(1) CNT from BO_EU_DNCTT_COMMISSION_PERIOD_AGENT where APPROVE_AND_POST_USER_ID IS NOT NULL AND LENGTH(APPROVE_AND_POST_USER_ID)>1 AND APPROVE_AND_POST_DATE IS NOT NULL AND  BINDID=? AND PERIOD_END_DATE>=?", new Object[]{bindid, PERIOD_END_DATE_Str}) > 0) {
+                        throw new BPMNError("已审批不允许修改开始日期和佣金金额");
+                    }
+
+                    int i = 0;
+                    if (DBSql.getInt("select count(1) CNT from BO_EU_DNCTT_COMMISSION_PERIOD where APPROVE_AND_POST_USER_ID IS NOT NULL AND LENGTH(APPROVE_AND_POST_USER_ID)>1 AND APPROVE_AND_POST_DATE IS NOT NULL AND  BINDID=?", new Object[]{bindid}) == 0) {
+                        i = i + 1;
+                    }
+
+                    if (DBSql.getInt("select count(1) CNT from BO_EU_DNCTT_COMMISSION_PERIOD_AGENT where APPROVE_AND_POST_USER_ID IS NOT NULL AND LENGTH(APPROVE_AND_POST_USER_ID)>1 AND APPROVE_AND_POST_DATE IS NOT NULL AND  BINDID=?", new Object[]{bindid}) == 0) {
+                        i = i + 1;
+                    }
+                    if (i == 2) {
+                        isRebuild = true;
+                    } else {
+                        //修改结束日期
+
+                    }
+                }
+            } else {
+//校验
+
+                //涉及到已审批的 不能修改
+
+
+
+            }
+            List<PERIOD> periodList = getPeriodList(RULE_CATE, PERIOD_BEGIN_DATE, PERIOD_END_DATE);//周期
+            if (periodList.size() > 0) {
+                Connection conn = null;
+                try {
+                    conn = DBSql.open();
+                    conn.setAutoCommit(false);
+
+                    //在未审批的情况下,修改开始日期或结束日期,删除所有佣金周期,重新生成
+                    if (isRebuild) {
+                        DBSql.update(conn, "DELETE FROM BO_EU_DNCTT_COMMISSION_PERIOD WHERE BINDID = ?", new Object[]{bindid});
+                        DBSql.update(conn, "DELETE FROM BO_EU_DNCTT_COMMISSION_PERIOD_AGENT WHERE BINDID = ?", new Object[]{bindid});
+                        DBSql.update(conn, "DELETE FROM BO_EU_DNCTT_COMMISSION_PERIOD_SALES WHERE BINDID = ?", new Object[]{bindid});
+                    } else {
+                        DBSql.update(conn, "DELETE FROM BO_EU_DNCTT_COMMISSION_PERIOD WHERE BINDID = ? AND PERIOD_BEGIN_DATE>? ", new Object[]{bindid, PERIOD_END_DATE_Str});
+                        DBSql.update(conn, "DELETE FROM BO_EU_DNCTT_COMMISSION_PERIOD_AGENT WHERE BINDID = ?  AND PERIOD_BEGIN_DATE>? ", new Object[]{bindid, PERIOD_END_DATE_Str});
+                        DBSql.update(conn, "DELETE FROM BO_EU_DNCTT_COMMISSION_PERIOD_SALES WHERE BINDID = ?  AND PERIOD_BEGIN_DATE>? ", new Object[]{bindid, PERIOD_END_DATE_Str});
+                    }
+
+                    List<BO> commissionAgentList = SDK.getBOAPI().query("BO_EU_DNCTT_COMMISSION_AGENT").addQuery("BINDID =", bindid).list();
+                    List<BO> commissionSalesList = SDK.getBOAPI().query("BO_EU_DNCTT_COMMISSION_SALES").addQuery("BINDID =", bindid).list();
+
+                    if (boName.equals("BO_EU_DNCTT_COMMISSION_ADJUST")) {
+                        PERIOD firstPeriod = periodList.get(0);
+                        if (firstPeriod.getRate().compareTo(BigDecimal.ONE) == 0) {
+                            String periodBOID = DBSql.getString(conn, "SELECT ID FROM BO_EU_DNCTT_COMMISSION_PERIOD WHERE PERIOD_BEGIN_DATE=? AND BINDID=?", new Object[]{firstPeriod.getPeriodBeginDateStr(), bindid});
+
+                            if (StringUtils.isBlank(periodBOID)) {
+                                periodBOID = DBSql.getString(conn, "SELECT ID FROM BO_EU_DNCTT_COMMISSION_PERIOD WHERE PERIOD_BEGIN_DATE<=? AND PERIOD_END_DATE>=? AND BINDID=?", new Object[]{firstPeriod.getPeriodBeginDateStr(), firstPeriod.getPeriodBeginDateStr(), bindid});
+
+                                if (StringUtils.isNotBlank(periodBOID)) {
+                                    BO periodBO = SDK.getBOAPI().get("BO_EU_DNCTT_COMMISSION_PERIOD", periodBOID);
+                                    LocalDate newPERIOD_END_DATE = PERIOD_BEGIN_DATE_final.minusDays(1);
+
+                                    BigDecimal periodRate = divideToBigDecimal(GetPeriodDays(getLocalDate(periodBO.getString("PERIOD_BEGIN_DATE")), newPERIOD_END_DATE), GetPeriodDays(getLocalDate(periodBO.getString("PERIOD_BEGIN_DATE")), getLocalDate(periodBO.getString("PERIOD_END_DATE"))));
+
+                                    String newPERIOD_END_DATE_str = newPERIOD_END_DATE.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+                                    periodBO.set("PERIOD_END_DATE", newPERIOD_END_DATE_str);
+                                    periodBO.set("COMMISSION_DOLLARS", multiply(periodRate, periodBO.get("COMMISSION_DOLLARS")));
+                                    periodBO.set("PERIOD_ADJUSTED_PRICE", periodBO.get("COMMISSION_DOLLARS"));
+                                    SDK.getBOAPI().update("BO_EU_DNCTT_COMMISSION_PERIOD", periodBO, conn);
+
+                                    String LAST_PERIOD_BEGIN_DATE_str = getLocalDate(periodBO.getString("PERIOD_BEGIN_DATE")).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+
+                                    //1 BO_EU_DNCTT_COMMISSION_PERIOD_AGENT
+                                    if (commissionAgentList.isEmpty() == false && commissionAgentList.size() > 0) {
+                                        for (BO commissionAgentBO : commissionAgentList) {
+
+                                            String periodAgentBOID = DBSql.getString(conn, "SELECT ID FROM BO_EU_DNCTT_COMMISSION_PERIOD_AGENT WHERE PERIOD_BEGIN_DATE=? AND BINDID=? AND AGENT=?", new Object[]{LAST_PERIOD_BEGIN_DATE_str, bindid, commissionAgentBO.get("AGENT")});
+
+                                            if (StringUtils.isBlank(periodAgentBOID)) {
+                                                BO periodAgentBO = SDK.getBOAPI().get("BO_EU_DNCTT_COMMISSION_PERIOD_AGENT", periodAgentBOID);
+                                                periodAgentBO.set("PERIOD_END_DATE", newPERIOD_END_DATE_str);
+                                                periodAgentBO.set("COMMISSION_DOLLARS", multiply(periodRate, periodAgentBO.get("COMMISSION_DOLLARS")));
+                                                periodAgentBO.set("PERIOD_ADJUSTED_PRICE", periodAgentBO.get("COMMISSION_DOLLARS"));
+                                                SDK.getBOAPI().update("BO_EU_DNCTT_COMMISSION_PERIOD_AGENT", periodAgentBO, conn);
+                                            }
+                                        }
+                                    }
+
+                                    //2 BO_EU_DNCTT_COMMISSION_PERIOD_SALES
+                                    if (commissionSalesList.isEmpty() == false && commissionSalesList.size() > 0) {
+                                        for (BO commissionSalesBO : commissionSalesList) {
+
+                                            String periodSalesBOID = DBSql.getString(conn, "SELECT ID FROM BO_EU_DNCTT_COMMISSION_PERIOD_SALES WHERE PERIOD_BEGIN_DATE=? AND BINDID=? AND SALESPERSON=?", new Object[]{LAST_PERIOD_BEGIN_DATE_str, bindid, commissionSalesBO.get("SALESPERSON")});
+
+                                            if (StringUtils.isNotBlank(periodSalesBOID)) {
+                                                BO periodSalesBO = SDK.getBOAPI().get("BO_EU_DNCTT_COMMISSION_PERIOD_AGENT", periodSalesBOID);
+                                                periodSalesBO.set("PERIOD_END_DATE", newPERIOD_END_DATE_str);
+                                                periodSalesBO.set("COMMISSION_DOLLARS", multiply(periodRate, periodSalesBO.get("COMMISSION_DOLLARS")));
+                                                periodSalesBO.set("PERIOD_ADJUSTED_PRICE", periodSalesBO.get("COMMISSION_DOLLARS"));
+                                                SDK.getBOAPI().update("BO_EU_DNCTT_COMMISSION_PERIOD_AGENT", periodSalesBO, conn);
+                                            }
+                                        }
+                                    }
+
+                                }
+                            }
+                        }
+                    }
+
+
+                    for (PERIOD period : periodList) {
+
+                        String periodBOID = DBSql.getString(conn, "SELECT ID FROM BO_EU_DNCTT_COMMISSION_PERIOD WHERE PERIOD_BEGIN_DATE=? AND BINDID=?", new Object[]{period.getPeriodBeginDateStr(), COMMISSION_BINDID});
+                        if (StringUtils.isNotBlank(periodBOID)) {
+                            BO periodBO = SDK.getBOAPI().get("BO_EU_DNCTT_COMMISSION_PERIOD", periodBOID);
+                            if (StringUtils.isNotBlank(periodBO.getString("APPROVE_AND_POST_USER_ID")) && StringUtils.isNotBlank(periodBO.getString("APPROVE_AND_POST_DATE"))) {
+                                //已审批,不能修改
+                            } else {
+                                periodBO.set("PERIOD_END_DATE", period.getPeriodEndDateStr());
+                                periodBO.set("COMMISSION_DOLLARS", multiply(period.getRate(), commissionBO.get("COMMISSION_DOLLARS")));
+                                periodBO.set("PERIOD_ADJUSTED_PRICE", periodBO.get("COMMISSION_DOLLARS"));
+                                SDK.getBOAPI().update("BO_EU_DNCTT_COMMISSION_PERIOD", periodBO, conn);
+                            }
+                        } else {
+                            //佣金周期
+                            BO periodBO = new BO();
+                            periodBO.set("ZB_BILLING_DATE", period.getPeriodMonthStr());
+                            periodBO.set("PERIOD_BEGIN_DATE", period.getPeriodBeginDateStr());
+                            periodBO.set("PERIOD_END_DATE", period.getPeriodEndDateStr());
+                            periodBO.set("COMMISSION_DOLLARS", multiply(period.getRate(), commissionBO.get("COMMISSION_DOLLARS")));
+                            periodBO.set("PERIOD_ADJUSTED_PRICE", periodBO.get("COMMISSION_DOLLARS"));
+                            periodBO.setBindId(COMMISSION_BINDID);
+                            SDK.getBOAPI().createDataBO("BO_EU_DNCTT_COMMISSION_PERIOD", periodBO, uc, conn);
+                        }
+                        //二级代理提成
+                        if (commissionAgentList.isEmpty() == false && commissionAgentList.size() > 0) {
+                            for (BO commissionAgentBO : commissionAgentList) {
+
+                                String periodAgentBOID = DBSql.getString(conn, "SELECT ID FROM BO_EU_DNCTT_COMMISSION_PERIOD_AGENT WHERE PERIOD_BEGIN_DATE=? AND BINDID=? AND AGENT=?", new Object[]{period.getPeriodBeginDateStr(), COMMISSION_BINDID, commissionAgentBO.get("AGENT")});
+
+                                if (StringUtils.isNotBlank(periodAgentBOID)) {
+                                    BO periodAgentBO = SDK.getBOAPI().get("BO_EU_DNCTT_COMMISSION_PERIOD_AGENT", periodAgentBOID);
+                                    if (StringUtils.isNotBlank(periodAgentBO.getString("APPROVE_AND_POST_USER_ID")) && StringUtils.isNotBlank(periodAgentBO.getString("APPROVE_AND_POST_DATE"))) {
+                                        //已审批,不能修改
+                                    } else {
+                                        periodAgentBO.set("PERIOD_END_DATE", period.getPeriodEndDateStr());
+                                        periodAgentBO.set("COMMISSION_DOLLARS", multiply(period.getRate(), commissionAgentBO.get("COMMISSION_DOLLARS")));
+                                        periodAgentBO.set("PERIOD_ADJUSTED_PRICE", periodAgentBO.get("COMMISSION_DOLLARS"));
+                                        SDK.getBOAPI().update("BO_EU_DNCTT_COMMISSION_PERIOD_AGENT", periodAgentBO, conn);
+                                    }
+                                } else {
+                                    BO periodAgentBO = new BO();
+                                    periodAgentBO.set("AGENT", commissionAgentBO.get("AGENT"));
+                                    periodAgentBO.set("PERIOD_BEGIN_DATE", period.getPeriodBeginDateStr());
+                                    periodAgentBO.set("PERIOD_END_DATE", period.getPeriodEndDateStr());
+                                    periodAgentBO.set("COMMISSION_DOLLARS", multiply(period.getRate(), commissionAgentBO.get("COMMISSION_DOLLARS")));
+                                    periodAgentBO.set("PERIOD_ADJUSTED_PRICE", periodAgentBO.get("COMMISSION_DOLLARS"));
+                                    periodAgentBO.setBindId(COMMISSION_BINDID);
+                                    SDK.getBOAPI().createDataBO("BO_EU_DNCTT_COMMISSION_PERIOD_AGENT", periodAgentBO, uc, conn);
+
+                                }
+                            }
+                        }
+
+                        //销售员佣金周期
+                        if (commissionSalesList.isEmpty() == false && commissionSalesList.size() > 0) {
+                            for (BO commissionSalesBO : commissionSalesList) {
+
+                                String periodSalesBOID = DBSql.getString(conn, "SELECT ID FROM BO_EU_DNCTT_COMMISSION_PERIOD_SALES WHERE PERIOD_BEGIN_DATE=? AND BINDID=? AND SALESPERSON=?", new Object[]{period.getPeriodBeginDateStr(), COMMISSION_BINDID, commissionSalesBO.get("SALESPERSON")});
+
+                                if (StringUtils.isNotBlank(periodSalesBOID)) {
+                                    BO periodSalesBO = SDK.getBOAPI().get("BO_EU_DNCTT_COMMISSION_PERIOD_AGENT", periodSalesBOID);
+                                    if (StringUtils.isNotBlank(periodSalesBO.getString("APPROVE_AND_POST_USER_ID")) && StringUtils.isNotBlank(periodSalesBO.getString("APPROVE_AND_POST_DATE"))) {
+                                        //已审批,不能修改
+                                    } else {
+                                        periodSalesBO.set("PERIOD_END_DATE", period.getPeriodEndDateStr());
+                                        periodSalesBO.set("COMMISSION_DOLLARS", multiply(period.getRate(), commissionSalesBO.get("COMMISSION_DOLLARS")));
+                                        periodSalesBO.set("PERIOD_ADJUSTED_PRICE", periodSalesBO.get("COMMISSION_DOLLARS"));
+                                        SDK.getBOAPI().update("BO_EU_DNCTT_COMMISSION_PERIOD_AGENT", periodSalesBO, conn);
+                                    }
+                                } else {
+                                    BO periodSalesBO = new BO();
+                                    periodSalesBO.set("SALESPERSON", commissionSalesBO.get("SALESPERSON"));
+                                    periodSalesBO.set("PERIOD_BEGIN_DATE", period.getPeriodBeginDateStr());
+                                    periodSalesBO.set("PERIOD_END_DATE", period.getPeriodEndDateStr());
+                                    periodSalesBO.set("COMMISSION_DOLLARS", multiply(period.getRate(), commissionSalesBO.get("COMMISSION_DOLLARS")));
+                                    periodSalesBO.set("PERIOD_ADJUSTED_PRICE", periodSalesBO.get("COMMISSION_DOLLARS"));
+                                    periodSalesBO.setBindId(COMMISSION_BINDID);
+                                    SDK.getBOAPI().createDataBO("BO_EU_DNCTT_COMMISSION_PERIOD_SALES", periodSalesBO, uc, conn);
+                                }
+                            }
+                        }
+                    }
+
+
+                    //更新佣金
+                    if (boName.equals("BO_EU_DNCTT_COMMISSION_ADJUST")) {
+
+                    }
+
+
+                    conn.commit();
+                } catch (SQLException e) {
+                    e.printStackTrace();
+                    conn.rollback();
+                } finally {
+                    if (conn != null) DBSql.close(conn);
+                }
+
+            }
+
+
+        }
+
+
+    }
+
+    /**
+     * 计算当前季度的总天数
+     */
+    private static int getDaysInCurrentQuarter(LocalDate date) {
+        // 获取当前月份
+        Month currentMonth = date.getMonth();
+        // 确定当前季度的起始月份和结束月份
+        Month startMonth = getQuarterStartMonth(currentMonth);
+        Month endMonth = getQuarterEndMonth(currentMonth);
+
+        // 构建季度的第一天(当月第一天)
+        LocalDate quarterStart = LocalDate.of(date.getYear(), startMonth, 1);
+
+        // 构建季度的最后一天(当月最后一天)
+        LocalDate quarterEnd = LocalDate.of(date.getYear(), endMonth, endMonth.length(date.isLeapYear()) // 考虑闰年2月的天数
+        );
+
+        // 计算两个日期之间的天数(包含首尾两天)
+        return (int) ChronoUnit.DAYS.between(quarterStart, quarterEnd) + 1;
+    }
+
+    /**
+     * 获取当前季度的起始月份
+     */
+    private static Month getQuarterStartMonth(Month month) {
+        int monthValue = month.getValue();
+        if (monthValue <= 3) {
+            return Month.JANUARY; // 第一季度:1-3月
+        } else if (monthValue <= 6) {
+            return Month.APRIL;   // 第二季度:4-6月
+        } else if (monthValue <= 9) {
+            return Month.JULY;    // 第三季度:7-9月
+        } else {
+            return Month.OCTOBER; // 第四季度:10-12月
+        }
+    }
+
+    /**
+     * 获取当前季度的结束月份
+     */
+    private static Month getQuarterEndMonth(Month month) {
+        int monthValue = month.getValue();
+        if (monthValue <= 3) {
+            return Month.MARCH;   // 第一季度结束月
+        } else if (monthValue <= 6) {
+            return Month.JUNE;    // 第二季度结束月
+        } else if (monthValue <= 9) {
+            return Month.SEPTEMBER; // 第三季度结束月
+        } else {
+            return Month.DECEMBER;  // 第四季度结束月
+        }
+    }
+
+    public static LocalDate getCommissNextPeriodStart(LocalDate start, String periodType) {
+        // 根据不同的周期类型计算下一周期的开始时间
+        switch (periodType) {
+            case cttConstant.COMMISSION_RULE_MONTH:
+                // 如果是月周期,则在当前时间基础上增加1个月
+                return start.plus(1, ChronoUnit.MONTHS);
+            case cttConstant.COMMISSION_RULE_QUARTER:
+                // 如果是季度周期,则在当前时间基础上增加3个月
+                return start.plus(3, ChronoUnit.MONTHS);
+            case cttConstant.COMMISSION_RULE_YEAR:
+                // 如果是年周期,则在当前时间基础上增加1年
+                return start.plus(1, ChronoUnit.YEARS);
+            default:
+                // 如果周期类型不匹配任何已知类型,则返回原始开始时间
+                return start;
+        }
+    }
+
+    /**
+     * 获取周期列表
+     * @param RULE_CATE
+     * @param PERIOD_BEGIN_DATE
+     * @param PERIOD_END_DATE
+     * @return
+     */
+    private List<PERIOD> getPeriodList(String RULE_CATE, LocalDate PERIOD_BEGIN_DATE, LocalDate PERIOD_END_DATE) {
+        List<PERIOD> periodList = new ArrayList<>();
+        //一次性收费
+        if (RULE_CATE.equals(cttConstant.COMMISSION_RULE_ONE_TIME)) {
+            PERIOD period = new PERIOD();
+            period.setPeriodBeginDate(PERIOD_BEGIN_DATE);
+            period.setPeriodEndDate(PERIOD_END_DATE);
+            period.setRate(BigDecimal.ONE);
+            periodList.add(period);
+        } else {
+            LocalDate START_DATE = null;
+            LocalDate currLastDay = null;
+            int periodDays = 0;
+            switch (RULE_CATE) {
+                case cttConstant.COMMISSION_RULE_MONTH://按月支付
+                {
+                    if (PERIOD_BEGIN_DATE.getDayOfMonth() != 1) {
+                        currLastDay = PERIOD_BEGIN_DATE.with(TemporalAdjusters.lastDayOfMonth());
+                        periodDays = PERIOD_BEGIN_DATE.lengthOfMonth();
+                    }
+                }
+                break;
+                case cttConstant.COMMISSION_RULE_QUARTER://按季支付
+                {
+                    //如果不是季度第一天
+                    if (PERIOD_BEGIN_DATE.getDayOfMonth() != 1 || (PERIOD_BEGIN_DATE.getMonthValue() - 1) % 3 != 0) {
+                        Month endMonth = getQuarterEndMonth(PERIOD_BEGIN_DATE.getMonth());
+                        currLastDay = LocalDate.of(PERIOD_BEGIN_DATE.getYear(), endMonth, endMonth.length(PERIOD_BEGIN_DATE.isLeapYear()) // 考虑闰年2月的天数
+                        );
+                        periodDays = getDaysInCurrentQuarter(PERIOD_BEGIN_DATE);
+                    }
+                }
+                break;
+                case cttConstant.COMMISSION_RULE_YEAR://按年支付
+                {
+                    //如果不是年第一天
+                    if (PERIOD_BEGIN_DATE.getDayOfMonth() != 1 || PERIOD_BEGIN_DATE.getMonthValue() != 1) {
+                        //所在年最后一天
+                        currLastDay = LocalDate.of(PERIOD_BEGIN_DATE.getYear(), 12, 31);
+                        periodDays = PERIOD_BEGIN_DATE.lengthOfYear();
+                    }
+                }
+                break;
+                default: {
+                    //报错,类型异常
+                    return null;
+                }
+            }
+
+            if (currLastDay != null) {
+                if (currLastDay.isBefore(PERIOD_END_DATE)) {
+                    PERIOD period = new PERIOD();
+                    period.setPeriodBeginDate(PERIOD_BEGIN_DATE);
+                    period.setPeriodEndDate(currLastDay);
+
+                    BigDecimal periodRate = divideToBigDecimal(GetPeriodDays(PERIOD_BEGIN_DATE, currLastDay), periodDays);
+                    period.setRate(periodRate);
+
+                    periodList.add(period);
+
+                    START_DATE = currLastDay.plusDays(1);//周期开始日期
+                } else {
+                    PERIOD period = new PERIOD();
+                    period.setPeriodBeginDate(PERIOD_BEGIN_DATE);
+                    period.setPeriodEndDate(PERIOD_END_DATE);
+
+                    BigDecimal periodRate = divideToBigDecimal(GetPeriodDays(PERIOD_BEGIN_DATE, PERIOD_END_DATE), periodDays);
+                    period.setRate(periodRate);
+
+                    periodList.add(period);
+                }
+            } else {
+                START_DATE = PERIOD_BEGIN_DATE;
+            }
+            //循环
+            if (START_DATE != null && START_DATE.isBefore(PERIOD_END_DATE)) {
+
+                while (!START_DATE.isAfter(PERIOD_END_DATE)) {
+                    LocalDate periodEnd = getCommissNextPeriodStart(START_DATE, RULE_CATE).minusDays(1);//本周期结束时间
+
+                    BigDecimal periodRate = BigDecimal.ONE;
+
+                    if (periodEnd.isAfter(PERIOD_END_DATE)) {//如果结束日期大于合同结束日期,则计算结束日期和合同结束日期的差值,并计算该差值占整周期的比例
+                        periodRate = divideToBigDecimal(GetPeriodDays(START_DATE, PERIOD_END_DATE), GetPeriodDays(START_DATE, periodEnd));
+                        periodEnd = PERIOD_END_DATE;
+                    }
+
+                    PERIOD period = new PERIOD();
+                    period.setPeriodBeginDate(START_DATE);
+                    period.setPeriodEndDate(periodEnd);
+                    period.setRate(periodRate);
+                    periodList.add(period);
+
+                    if (periodEnd != null) {
+                        START_DATE = periodEnd.plusDays(1);
+                    }
+                }
+            }
+
+        }
+        return periodList;
+    }
+
+
+    private class PERIOD {
+        private LocalDate PERIOD_BEGIN_DATE;
+        private LocalDate PERIOD_END_DATE;
+
+        private BigDecimal RATE;
+
+        public void setPeriodBeginDate(LocalDate periodBeginDate) {
+            this.PERIOD_BEGIN_DATE = periodBeginDate;
+        }
+
+        public void setPeriodEndDate(LocalDate periodEndDate) {
+            this.PERIOD_END_DATE = periodEndDate;
+        }
+
+        public void setRate(BigDecimal rate) {
+            this.RATE = rate;
+        }
+
+        public LocalDate getPeriodBeginDate() {
+            return PERIOD_BEGIN_DATE;
+        }
+
+        public LocalDate getPeriodEndDate() {
+            return PERIOD_END_DATE;
+        }
+
+        public String getPeriodBeginDateStr() {
+            return PERIOD_BEGIN_DATE.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+        }
+
+        public String getPeriodMonthStr() {
+            return PERIOD_BEGIN_DATE.format(DateTimeFormatter.ofPattern("yyyyMM"));
+        }
+
+        public String getPeriodEndDateStr() {
+            return PERIOD_END_DATE.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+        }
+
+        public BigDecimal getRate() {
+            return RATE;
+        }
+
+    }
+}

+ 61 - 0
com.awspaas.user.apps.donenow_ctt/src/com/awspaas/user/apps/donenow_ctt/event/commissionFormBeforeSave.java

@@ -0,0 +1,61 @@
+package com.awspaas.user.apps.donenow_ctt.event;
+
+import com.actionsoft.bpms.bo.engine.BO;
+import com.actionsoft.bpms.bpmn.engine.core.delegate.ProcessExecutionContext;
+import com.actionsoft.bpms.bpmn.engine.listener.InterruptListener;
+import com.actionsoft.bpms.bpmn.engine.listener.ListenerConst;
+import com.actionsoft.bpms.util.DBSql;
+import com.actionsoft.exception.BPMNError;
+import com.actionsoft.sdk.local.SDK;
+import org.apache.commons.lang3.StringUtils;
+
+import java.time.LocalDate;
+
+import static com.awspaas.user.apps.donenow_ctt.service.contractService.getLocalDate;
+import static com.awspaas.user.apps.donenow_ctt.service.contractService.isApproximatelyEqual;
+
+public class commissionFormBeforeSave extends InterruptListener {
+    public String getDescription() {
+        return "合同表单保存前的事件测试";
+    }
+
+
+    @Override
+    public boolean execute(ProcessExecutionContext param) throws Exception {
+
+        String boId = param.getParameterOfString(ListenerConst.FORM_EVENT_PARAM_BOID);
+        String boName = param.getParameterOfString(ListenerConst.FORM_EVENT_PARAM_BONAME);
+        BO formData = (BO) param.getParameter(ListenerConst.FORM_EVENT_PARAM_FORMDATA);
+        String bindid = param.getProcessInstance().getId();
+
+        LocalDate PERIOD_BEGIN_DATE = getLocalDate(formData.get("PERIOD_BEGIN_DATE"));//开始日期
+        LocalDate PERIOD_END_DATE = getLocalDate(formData.get("PERIOD_END_DATE"));//结束日期
+        String RULE_CATE = formData.getString("RULE_CATE");//佣金规则
+        if (boName.equals("BO_EU_DNCTT_COMMISSION")) {
+            BO orgData = SDK.getBOAPI().get(boName, formData.getId());
+
+            //已审批 不允许修改 开始日期和佣金金额
+            String PERIOD_BEGIN_DATE_MIN = DBSql.getString("SELECT MIN(PERIOD_BEGIN_DATE) FROM BO_EU_DNCTT_COMMISSION_PERIOD WHERE BINDID = '" + bindid + "'");
+
+            if (StringUtils.isNotBlank(PERIOD_BEGIN_DATE_MIN) && !PERIOD_BEGIN_DATE.equals(getLocalDate(PERIOD_BEGIN_DATE_MIN)) || !isApproximatelyEqual(orgData.get("COMMISSION_DOLLARS"), formData.get("COMMISSION_DOLLARS"))) {
+                //开始日期已修改
+
+                //已审批不允许修改
+                if (DBSql.getInt("select count(1) CNT from BO_EU_DNCTT_COMMISSION_PERIOD where APPROVE_AND_POST_USER_ID IS NOT NULL AND LENGTH(APPROVE_AND_POST_USER_ID)>1 AND APPROVE_AND_POST_DATE IS NOT NULL AND  BINDID=?", new Object[]{bindid}) > 0) {
+                    throw new BPMNError("500", "已审批不允许修改开始日期和佣金金额");
+                }
+
+                if (DBSql.getInt("select count(1) CNT from BO_EU_DNCTT_COMMISSION_PERIOD_AGENT where APPROVE_AND_POST_USER_ID IS NOT NULL AND LENGTH(APPROVE_AND_POST_USER_ID)>1 AND APPROVE_AND_POST_DATE IS NOT NULL AND  BINDID=?", new Object[]{bindid}) > 0) {
+                    throw new BPMNError("500", "已审批不允许修改开始日期和佣金金额");
+                }
+            }
+        }else if (boName.equals("BO_EU_DNCTT_COMMISSION_ADJUST")) {
+            //
+
+
+
+        }
+        return true;
+    }
+
+}

+ 48 - 0
com.awspaas.user.apps.donenow_ctt/src/com/awspaas/user/apps/donenow_ctt/service/contractService.java

@@ -1394,6 +1394,54 @@ public class contractService {
         return BigDecimal.ZERO; // 返回默认值 0
     }
 
+    // 误差范围:0.00001
+    private static final BigDecimal EPSILON = new BigDecimal("0.00001");
+
+    /**
+     * 将Object转换为BigDecimal
+     * @param obj 待转换的对象(支持Number、String等可转换为数字的类型)
+     * @return 转换后的BigDecimal
+     * @throws IllegalArgumentException 若对象无法转换为BigDecimal
+     */
+    public static BigDecimal toBigDecimal(Object obj) {
+        if (obj == null) {
+            throw new IllegalArgumentException("对象不能为null");
+        }
+
+        if (obj instanceof BigDecimal) {
+            return (BigDecimal) obj;
+        } else if (obj instanceof Number) {
+            // 处理数字类型(Integer、Double、Long等)
+            return new BigDecimal(obj.toString());
+        } else if (obj instanceof String) {
+            // 处理字符串类型(需符合数字格式)
+            try {
+                return new BigDecimal((String) obj);
+            } catch (NumberFormatException e) {
+                throw new IllegalArgumentException("字符串无法转换为BigDecimal: " + obj, e);
+            }
+        } else {
+            throw new IllegalArgumentException("不支持的类型转换: " + obj.getClass().getName());
+        }
+    }
+
+    /**
+     * 判断两个Object转换后的BigDecimal是否在0.00001误差范围内相等
+     * @param obj1 第一个对象
+     * @param obj2 第二个对象
+     * @return true(误差范围内相等),false(不相等)
+     */
+    public static boolean isApproximatelyEqual(Object obj1, Object obj2) {
+        BigDecimal bd1 = toBigDecimal(obj1);
+        BigDecimal bd2 = toBigDecimal(obj2);
+
+        // 计算两个数的差值绝对值
+        BigDecimal difference = bd1.subtract(bd2).abs();
+
+        // 比较差值是否小于等于误差范围
+        return difference.compareTo(EPSILON) <= 0;
+    }
+
     /**
      * 返回合同周期天数除以服务周期天数的比例,保留8位小数
      * @param contractPeriod