소스 검색

Merge branch 'master' of http://210.51.45.41:3000/itcat_admin/aws_donenow

HULEI 2 달 전
부모
커밋
bb666d2e60

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

@@ -0,0 +1,83 @@
+package com.awspaas.user.apps.donenow_ctt.controller;
+
+import com.actionsoft.bpms.bo.engine.BO;
+import com.actionsoft.bpms.bpmn.engine.model.run.delegate.ProcessInstance;
+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;
+import com.actionsoft.sdk.local.SDK;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+
+@Controller
+public class commissionController {
+    /**
+     * 佣金调整
+     * @param uc
+     * @param commissionBindid
+     * @return
+     */
+    @Mapping(value = "com.awspaas.user.apps.donenow_ctt.commission_adjust")
+    public ResponseObject commissionAdjust(UserContext uc, String commissionBindid) {
+
+        BO commissionBO = SDK.getBOAPI().getByProcess("BO_EU_DNCTT_COMMISSION", commissionBindid);
+        List<BO> commissionAgentList = SDK.getBOAPI().query("BO_EU_DNCTT_COMMISSION_AGENT").addQuery("BINDID =", commissionBindid).list();
+        List<BO> commissionSalesList = SDK.getBOAPI().query("BO_EU_DNCTT_COMMISSION_SALES").addQuery("BINDID =", commissionBindid).list();
+
+        commissionBO.remove("ID");
+        commissionBO.remove("BINDID");
+
+        ProcessInstance contractInstance = SDK.getProcessAPI().createBOProcessInstance("obj_290337ce889c4a1295852e7b76aa82d4", uc.getUID(), "佣金调整-" + "-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
+
+        BO editBO = new BO();
+        commissionBO.remove("CREATEDATE");
+        commissionBO.remove("CREATEUSER");
+        editBO.setAll(commissionBO.asMap());
+        editBO.set("OLD_COMMISSION_DOLLARS", commissionBO.get("COMMISSION_DOLLARS"));
+        editBO.set("OLD_RATIO", commissionBO.get("DOLLARS"));
+        editBO.set("COMMISSION_BINDID", commissionBindid);
+        editBO.set("OLD_DOLLARS", "未执行");
+        SDK.getBOAPI().create("BO_EU_DNCTT_COMMISSION_ADJUST", editBO, contractInstance, uc);
+
+        if (commissionAgentList != null && commissionAgentList.size() > 0) {
+            for (BO bo : commissionAgentList) {
+                BO editAgentBO = new BO();
+                bo.remove("CREATEDATE");
+                bo.remove("CREATEUSER");
+                editAgentBO.setAll(bo.asMap());
+                editAgentBO.set("OLD_RATIO", bo.get("RATIO"));
+                editAgentBO.set("OLD_DOLLARS", bo.get("DOLLARS"));
+                editAgentBO.set("OLD_TAX_DEDUCT", bo.get("TAX_DEDUCT"));
+                editAgentBO.set("OLD_COMMISSION_DOLLARS", bo.get("COMMISSION_DOLLARS"));
+                SDK.getBOAPI().create("BO_EU_DNCTT_COMMISSION_AGENT_ADJUST", editAgentBO, contractInstance, uc);
+            }
+        }
+
+        if (commissionSalesList != null && commissionSalesList.size() > 0) {
+            for (BO bo : commissionSalesList) {
+                BO editSalesBO = new BO();
+                bo.remove("CREATEDATE");
+                bo.remove("CREATEUSER");
+                editSalesBO.setAll(bo.asMap());
+                editSalesBO.set("OLD_RATIO", bo.get("RATIO"));
+                editSalesBO.set("OLD_DOLLARS", bo.get("DOLLARS"));
+                editSalesBO.set("OLD_TAX_DEDUCT", bo.get("TAX_DEDUCT"));
+                editSalesBO.set("OLD_COMMISSION_DOLLARS", bo.get("COMMISSION_DOLLARS"));
+                SDK.getBOAPI().create("BO_EU_DNCTT_COMMISSION_SALES_ADJUST", editSalesBO, contractInstance, uc);
+            }
+        }
+
+
+        String processUrl = SDK.getFormAPI().getFormURL(SDK.getPortalAPI().getPortalUrl(), uc.getSessionId(), contractInstance.getId(), null, 1, null, editBO.getId(), null, true);
+
+        ResponseObject responseObject = ResponseObject.newOkResponse();
+        responseObject.setData(processUrl);
+
+        return responseObject;
+    }
+
+
+}

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

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

@@ -0,0 +1,551 @@
+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();
+
+        String _ADJUST = StringUtils.EMPTY;
+        if (boName.equals("BO_EU_DNCTT_COMMISSION_ADJUST")) {
+            _ADJUST = "_ADJUST";
+        }
+        //佣金表单和佣金调整表单 保存时触发
+        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 {
+                //校验
+                LocalDate EFFECTIVE_DATE = getLocalDate(commissionBO.get("PERIOD_BEGIN_DATE"));//服务生效日期
+                String EFFECTIVE_DATE_STR = EFFECTIVE_DATE.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+
+                if (DBSql.getInt("SELECT count(1) 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[]{commissionBO.get("COMMISSION_BINDID"), EFFECTIVE_DATE_STR}) > 0) {
+                    throw new BPMNError("500", EFFECTIVE_DATE_STR + "之后的佣金周期已被审批,则不能修改到当前日期");
+                }
+
+                if (DBSql.getInt("SELECT count(1) 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[]{commissionBO.get("COMMISSION_BINDID"), EFFECTIVE_DATE_STR}) > 0) {
+                    throw new BPMNError("500", EFFECTIVE_DATE_STR + "之后的佣金周期已被审批,则不能修改到当前日期");
+                }
+            }
+
+
+            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" + _ADJUST).addQuery("BINDID =", bindid).list();
+                    List<BO> commissionSalesList = SDK.getBOAPI().query("BO_EU_DNCTT_COMMISSION_SALES" + _ADJUST).addQuery("BINDID =", bindid).list();
+
+                    if (boName.equals("BO_EU_DNCTT_COMMISSION_ADJUST")) {
+
+                        //当前生效日期之后的调整设置为 作废
+                        List<BO> editServiceList = SDK.getBOAPI().query("BO_EU_DNCTT_COMMISSION_ADJUST").connection(conn).addQuery("COMMISSION_BINDID =", COMMISSION_BINDID).addQuery("IS_EFFECTIVE =", "已执行").addQuery("PERIOD_BEGIN_DATE >", PERIOD_BEGIN_DATE_final.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))).orderBy("PERIOD_BEGIN_DATE").asc().list();
+
+                        if (editServiceList != null && editServiceList.size() > 0) {
+                            //在此次调整之后有新的
+                            for (BO editServiceOld : editServiceList) {
+                                editServiceOld.set("IS_EFFECTIVE", "作废");
+                                SDK.getBOAPI().update("BO_EU_DNCTT_COMMISSION_ADJUST", editServiceOld, conn);
+                            }
+                        }
+
+                        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")) {
+                        commissionBO.set("IS_EFFECTIVE", "已执行");
+                        SDK.getBOAPI().update("BO_EU_DNCTT_COMMISSION_ADJUST", commissionBO, conn);
+                    }
+
+                    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;
+        }
+
+    }
+}

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

@@ -0,0 +1,70 @@
+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 java.time.format.DateTimeFormatter;
+
+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")) {
+            //校验
+            LocalDate EFFECTIVE_DATE = getLocalDate(formData.get("PERIOD_BEGIN_DATE"));//服务生效日期
+            String EFFECTIVE_DATE_STR = EFFECTIVE_DATE.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+
+            if (DBSql.getInt("SELECT count(1) 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[]{formData.get("COMMISSION_BINDID"), EFFECTIVE_DATE_STR}) > 0) {
+                throw new BPMNError("500", EFFECTIVE_DATE_STR + "之后的佣金周期已被审批,则不能修改到当前日期");
+            }
+
+            if (DBSql.getInt("SELECT count(1) 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[]{formData.get("COMMISSION_BINDID"), EFFECTIVE_DATE_STR}) > 0) {
+                throw new BPMNError("500", EFFECTIVE_DATE_STR + "之后的佣金周期已被审批,则不能修改到当前日期");
+            }
+
+        }
+        return true;
+    }
+
+}

+ 367 - 255
com.awspaas.user.apps.donenow_ctt/src/com/awspaas/user/apps/donenow_ctt/service/contractService.java

@@ -273,9 +273,11 @@ public class contractService {
 
             for (BO service : serviceList) {
                 AddServiceServiceBundleOne(uc, conn, contract, service);
-
+                //一次性收费服务 不受开始日期或结束日期影响
+                if (service.getString("PERIOD_TYPE").equals(cttConstant.PERIOD_TYPE_ONE_TIME)) {
+                    continue;
+                }
                 contractServiceLogger.info("判断合同结束日期是否修改");
-
                 //如果服务周期的结束时间不等于合同的结束时间,则需要延长服务周期或缩短
                 String PERIOD = service.getString("PERIOD");//服务起止日期
                 String ADJUST_PERIOD = service.getString("ADJUST_PERIOD");//服务调整的起止日期
@@ -301,6 +303,8 @@ public class contractService {
 
                 contractServiceLogger.info("服务周期结束日期--" + LocalDateYYYYMMDD(PERIOD_END));
                 contractServiceLogger.info("合同结束日期--" + LocalDateYYYYMMDD(END_DATE));
+
+
                 if (PERIOD_END.isEqual(END_DATE)) {
                     if (PERIOD_END.isBefore(END_DATE)) {
                         contractServiceLogger.info("服务周期延长--" + service.getString("NAME"));
@@ -581,17 +585,15 @@ public class contractService {
             service.set("UNIT_COST", unit_cost);
             unit_price = unit_price.multiply(rate);
             service.set("UNIT_PRICE", unit_price);
-
-            service.set("PERIOD_TYPE", contract.getString("PERIOD_TYPE"));//计费周期更新
+            // service.set("PERIOD_TYPE", contract.getString("PERIOD_TYPE"));//计费周期更新
+            service.set("PERIOD_TYPE", maxPeriod);
         }
 
         contractServiceLogger.info("计算-service-ADJUSTED_PRICE");
-
         service.set("TOTAL_PRICE", multiply(service.get("QUANTITY"), service.get("UNIT_PRICE")));//总价
         service.set("ADJUSTED_PRICE", multiply(service.get("QUANTITY"), service.get("UNIT_PRICE")));//总价
         service.set("TOTAL_COST", multiply(service.get("QUANTITY"), service.get("UNIT_COST")));//总价
 
-
         SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_SERVICE", service, conn);//保存
 
         List<String> sbsList = null;
@@ -633,6 +635,45 @@ public class contractService {
                 START_DATE = currMontLastDay.plusDays(1);//周期开始日期
         }
 
+
+        //2025年10月15日 一次性收费服务
+        if (service.getString("PERIOD_TYPE").equals(cttConstant.PERIOD_TYPE_ONE_TIME)) {
+            BO csp = new BO();//服务周期
+            csp.set("CONTRACT_ID", contract.get("ID"));
+            csp.set("OBJECT_ID", service.get("OBJECT_ID"));
+            csp.set("OBJECT_TYPE", service.get("OBJECT_TYPE"));
+            csp.set("CONTRACT_SERVICE_ID", service.get("ID"));
+            csp.set("PERIOD_BEGIN_DATE", EFFECTIVE_DATE);
+            csp.set("PERIOD_END_DATE", END_DATE);
+            csp.set("QUANTITY", service.get("QUANTITY"));
+            BigDecimal period_price = multiply(service.get("UNIT_PRICE"), service.get("QUANTITY"));
+            csp.set("PERIOD_PRICE", period_price);
+            BigDecimal period_cost = multiply(service.get("UNIT_COST"), service.get("QUANTITY"));
+            csp.set("PERIOD_COST", period_cost);
+            csp.set("PERIOD_ADJUSTED_PRICE", csp.get("PERIOD_PRICE"));
+            csp.set("VENDOR_ACCOUNT_ID", vendor_account_id);
+            csp.setBindId(service.getString("BINDID"));
+            SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", csp, uc, conn);
+
+            if (service.getString("OBJECT_TYPE").equals("2"))//服务包
+            {
+                //本周期成本
+                String prorated_cost_change = DBSql.getString(conn, "select UNIT_COST from BO_EU_DNIVT_SERVICE where ID=?", new Object[]{service.getString("OBJECT_ID")});//供应商账号
+                if (sbsList != null) {
+                    for (String sbs : sbsList) {
+                        BO cspbs = new BO();
+                        cspbs.set("CONTRACT_SERVICE_PERIOD_ID", csp.getId());
+                        cspbs.set("SERVICE_ID", sbs);
+                        cspbs.set("VENDOR_ACCOUNT_ID", vendor_account_id);
+                        cspbs.set("PERIOD_COST", prorated_cost_change);
+                        cspbs.setBindId(service.getString("BINDID"));
+                        SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE", cspbs, uc, conn);
+                    }
+                }
+            }
+            return true;
+        }
+
         // 计算首周期起止日期,并判断是否需要新增服务调整记录
         Map<String, Object> firstPeriodDate = getFirstPeriodDate(START_DATE, END_DATE, EFFECTIVE_DATE, contract.getString("PERIOD_TYPE"), service.getString("PERIOD_TYPE"));
         boolean isStartOfPeriod = (boolean) firstPeriodDate.get("isStartOfPeriod");//是否需要服务调整
@@ -782,309 +823,332 @@ public class contractService {
         LocalDate EFFECTIVE_DATE = getLocalDate(editService.get("EFFECTIVE_DATE"));//服务生效日期
         String EFFECTIVE_DATE_STR = EFFECTIVE_DATE.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
 
-        //生效日期之后有审批通过的;
-        if (DBSql.getInt("SELECT count(1) FROM BO_EU_DNCTT_CONTRACT_SERVICE_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 CONTRACT_ID=? and CONTRACT_SERVICE_ID=? AND  PERIOD_END_DATE>=?", new Object[]{contract.get("ID"), editService.get("CONTRACT_SERVICE_ID"), EFFECTIVE_DATE_STR}) > 0) {
-            return false;
-        }
-
-        List<BO> editServiceList = SDK.getBOAPI().query("BO_EU_DNCTT_CONTRACT_SERVICE_EDIT").connection(conn).addQuery("CONTRACT_SERVICE_ID =", editService.getString("CONTRACT_SERVICE_ID")).addQuery("IS_EFFECTIVE =", "已执行").addQuery("EFFECTIVE_DATE >", EFFECTIVE_DATE_STR).orderBy("EFFECTIVE_DATE").asc().list();
+        //2025年10月15日 一次性收费服务
+        if (editService.getString("PERIOD_TYPE").equals(cttConstant.PERIOD_TYPE_ONE_TIME)) {
 
-        boolean needDel = false;//是否需要删除重新生成
-        if (editServiceList != null && editServiceList.size() > 0) {
-            needDel = true;
-            //在此次调整之后有新的
-            for (BO editServiceOld : editServiceList) {
-                editServiceOld.set("IS_EFFECTIVE", "作废");
-                SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_SERVICE_EDIT", editServiceOld, conn);
+            //有审批通过的;
+            if (DBSql.getInt("SELECT count(1) FROM BO_EU_DNCTT_CONTRACT_SERVICE_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 CONTRACT_ID=? and CONTRACT_SERVICE_ID=? ", new Object[]{contract.get("ID"), editService.get("CONTRACT_SERVICE_ID")}) > 0) {
+                return false;
+            }
+        } else {
+            //生效日期之后有审批通过的;
+            if (DBSql.getInt("SELECT count(1) FROM BO_EU_DNCTT_CONTRACT_SERVICE_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 CONTRACT_ID=? and CONTRACT_SERVICE_ID=? AND  PERIOD_END_DATE>=?", new Object[]{contract.get("ID"), editService.get("CONTRACT_SERVICE_ID"), EFFECTIVE_DATE_STR}) > 0) {
+                return false;
             }
         }
 
-        //服务调整的生效日期,是按照日期顺序创建的
-        if (needDel == false) {
 
-            contractServiceLogger.info("服务调整的生效日期,是按照日期顺序创建的");
+        //一次性收费服务
+        if (editService.getString("PERIOD_TYPE").equals(cttConstant.PERIOD_TYPE_ONE_TIME)) {
+            BO servicePeriod = SDK.getBOAPI().query("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD").connection(conn).addQuery("CONTRACT_SERVICE_ID =", editService.getString("CONTRACT_SERVICE_ID")).detail();
+            servicePeriod.set("PERIOD_BEGIN_DATE", EFFECTIVE_DATE);
+            servicePeriod.set("QUANTITY", editService.get("QUANTITY"));
+            servicePeriod.set("PERIOD_PRICE", editService.get("TOTAL_PRICE"));
+            servicePeriod.set("PERIOD_COST", editService.get("TOTAL_COST"));
 
-            List<BO> servicePeriodList = SDK.getBOAPI().query("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD").connection(conn).addQuery("CONTRACT_SERVICE_ID =", editService.getString("CONTRACT_SERVICE_ID")).orderBy("PERIOD_BEGIN_DATE").asc().list();
+            servicePeriod.set("PERIOD_ADJUSTED_PRICE", servicePeriod.get("PERIOD_PRICE"));
+            SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", servicePeriod, conn);
 
-            if (servicePeriodList != null && servicePeriodList.size() > 0) {
+        } else {
 
-                for (BO servicePeriod : servicePeriodList) {
-                    LocalDate period_begin_date = getLocalDate(servicePeriod.get("PERIOD_BEGIN_DATE"));
-                    LocalDate period_end_date = getLocalDate(servicePeriod.get("PERIOD_END_DATE"));
 
-                    //调整日期之前,不用修改
-                    if (period_end_date.isBefore(EFFECTIVE_DATE)) {
-                        continue;
-                    }
-                    //处于调整日期之后的
-                    if (period_begin_date.isBefore(EFFECTIVE_DATE) && !period_end_date.isBefore(EFFECTIVE_DATE)) {
-                        //分成调整前和调整后 两条计费周期
-                        //新的计费周期
-                        BO servicePeriodAdj = new BO();
-                        servicePeriodAdj.setAll(servicePeriod.asMap());
-                        servicePeriodAdj.setId(null);
-                        servicePeriodAdj.set("PERIOD_BEGIN_DATE", EFFECTIVE_DATE);
-                        servicePeriodAdj.set("PERIOD_END_DATE", period_end_date);
-                        servicePeriodAdj.set("QUANTITY", editService.get("QUANTITY"));
-
-                        String ORG_PERIOD_ID = servicePeriod.getString("ORG_PERIOD_ID");
-                        if (StringUtils.isBlank(ORG_PERIOD_ID))
-                            ORG_PERIOD_ID = servicePeriod.getId();
-                        servicePeriodAdj.set("ORG_PERIOD_ID", ORG_PERIOD_ID);
-
-                        BigDecimal periodRateAdj = divideToBigDecimal(GetPeriodDays(EFFECTIVE_DATE, period_end_date), GetPeriodDays(period_begin_date, period_end_date));
-
-                        BigDecimal priceRate = editService.get("TOTAL_PRICE", BigDecimal.class).divide(editService.get("OLD_TOTAL_PRICE", BigDecimal.class), 10, RoundingMode.HALF_UP);
-                        BigDecimal costRate = editService.get("TOTAL_COST", BigDecimal.class).divide(editService.get("OLD_TOTAL_COST", BigDecimal.class), 10, RoundingMode.HALF_UP);
-
-                        servicePeriodAdj.set("PERIOD_PRICE", multiply(servicePeriod.get("PERIOD_PRICE"), multiply(periodRateAdj, priceRate)));
-                        servicePeriodAdj.set("PERIOD_COST", multiply(servicePeriod.get("PERIOD_COST"), multiply(periodRateAdj, costRate)));
-                        servicePeriodAdj.set("PERIOD_ADJUSTED_PRICE", servicePeriodAdj.get("PERIOD_PRICE"));
-                        SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", servicePeriodAdj, uc, conn);
-
-
-                        List<BO> sbsList = SDK.getBOAPI().query("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE").connection(conn).addQuery("CONTRACT_SERVICE_PERIOD_ID =", ORG_PERIOD_ID).list();
-                        if (sbsList != null && sbsList.size() > 0)
-                            for (BO sbs : sbsList) {
-                                BO newSbs = new BO();
-                                newSbs.setAll(sbs.asMap());
-                                newSbs.setId(null);
-                                newSbs.set("CONTRACT_SERVICE_PERIOD_ID", servicePeriodAdj.getId());
-                                SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE", newSbs, uc, conn);
-                            }
+            List<BO> editServiceList = SDK.getBOAPI().query("BO_EU_DNCTT_CONTRACT_SERVICE_EDIT").connection(conn).addQuery("CONTRACT_SERVICE_ID =", editService.getString("CONTRACT_SERVICE_ID")).addQuery("IS_EFFECTIVE =", "已执行").addQuery("EFFECTIVE_DATE >", EFFECTIVE_DATE_STR).orderBy("EFFECTIVE_DATE").asc().list();
 
-                        //旧的计费周期更新
-                        servicePeriod.set("PERIOD_END_DATE", EFFECTIVE_DATE.minusDays(1));
-                        BigDecimal periodRate = divideToBigDecimal(GetPeriodDays(period_begin_date, EFFECTIVE_DATE.minusDays(1)), GetPeriodDays(period_begin_date, period_end_date));
-                        servicePeriod.set("PERIOD_PRICE", multiply(servicePeriod.get("PERIOD_PRICE"), periodRate));
-                        servicePeriod.set("PERIOD_COST", multiply(servicePeriod.get("PERIOD_COST"), periodRate));
-                        servicePeriod.set("PERIOD_ADJUSTED_PRICE", servicePeriod.get("PERIOD_PRICE"));
-                        servicePeriod.set("ORG_PERIOD_ID", ORG_PERIOD_ID);
-                        SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", servicePeriod, conn);
-                    } else {
-                        //重新计算
-                        BigDecimal priceRate = editService.get("TOTAL_PRICE", BigDecimal.class).divide(editService.get("OLD_TOTAL_PRICE", BigDecimal.class), 10, RoundingMode.HALF_UP);
-                        BigDecimal costRate = editService.get("TOTAL_COST", BigDecimal.class).divide(editService.get("OLD_TOTAL_COST", BigDecimal.class), 10, RoundingMode.HALF_UP);
-                        servicePeriod.set("QUANTITY", editService.get("QUANTITY"));
-                        servicePeriod.set("PERIOD_PRICE", multiply(servicePeriod.get("PERIOD_PRICE"), priceRate));
-                        servicePeriod.set("PERIOD_COST", multiply(servicePeriod.get("PERIOD_COST"), costRate));
-                        servicePeriod.set("PERIOD_ADJUSTED_PRICE", servicePeriod.get("PERIOD_PRICE"));
-                        SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", servicePeriod, conn);
-                    }
+            boolean needDel = false;//是否需要删除重新生成
+            if (editServiceList != null && editServiceList.size() > 0) {
+                needDel = true;
+                //在此次调整之后有新的
+                for (BO editServiceOld : editServiceList) {
+                    editServiceOld.set("IS_EFFECTIVE", "作废");
+                    SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_SERVICE_EDIT", editServiceOld, conn);
                 }
             }
 
-        } else {
-            contractServiceLogger.info("本次服务调整生效日期之后的服务调整全部作废");
-
-            //生效日期之后的
-            List<BO> servicePeriodList = SDK.getBOAPI().query("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD").connection(conn).addQuery("CONTRACT_SERVICE_ID =", editService.getString("CONTRACT_SERVICE_ID")).addQuery("PERIOD_END_DATE >=", EFFECTIVE_DATE_STR).orderBy("PERIOD_BEGIN_DATE").asc().list();
-
-            BO firstServicePeriod = servicePeriodList.get(0);
-            //判断是不是个整周期
-            String ORG_PERIOD_ID = firstServicePeriod.getString("ORG_PERIOD_ID");
-
-            LocalDate SATRT_DATE = null;
-            if (StringUtils.isBlank(ORG_PERIOD_ID)) {
-                ORG_PERIOD_ID = firstServicePeriod.getString("ORG_PERIOD_ID");
-                LocalDate period_begin_date = getLocalDate(firstServicePeriod.get("PERIOD_BEGIN_DATE"));
-                LocalDate period_end_date = getLocalDate(firstServicePeriod.get("PERIOD_END_DATE"));
-
-                //新的计费周期
-                BO servicePeriodAdj = new BO();
-
-                servicePeriodAdj.setAll(firstServicePeriod.asMap());
-                servicePeriodAdj.setId(null);
-
-                servicePeriodAdj.set("PERIOD_BEGIN_DATE", EFFECTIVE_DATE);
-                servicePeriodAdj.set("PERIOD_END_DATE", period_end_date);
-                servicePeriodAdj.set("QUANTITY", editService.get("QUANTITY"));
-                servicePeriodAdj.set("ORG_PERIOD_ID", ORG_PERIOD_ID);
-
-                BigDecimal periodRateAdj = divideToBigDecimal(GetPeriodDays(EFFECTIVE_DATE, period_end_date), GetPeriodDays(period_begin_date, period_end_date));
-
-                BigDecimal priceRate = editService.get("TOTAL_PRICE", BigDecimal.class).divide(editService.get("OLD_TOTAL_PRICE", BigDecimal.class), 10, RoundingMode.HALF_UP);
-                BigDecimal costRate = editService.get("TOTAL_COST", BigDecimal.class).divide(editService.get("OLD_TOTAL_COST", BigDecimal.class), 10, RoundingMode.HALF_UP);
-
-                servicePeriodAdj.set("PERIOD_PRICE", multiply(firstServicePeriod.get("PERIOD_PRICE"), multiply(periodRateAdj, priceRate)));
-                servicePeriodAdj.set("PERIOD_COST", multiply(firstServicePeriod.get("PERIOD_COST"), multiply(periodRateAdj, costRate)));
-                servicePeriodAdj.set("PERIOD_ADJUSTED_PRICE", servicePeriodAdj.get("PERIOD_PRICE"));
-                SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", servicePeriodAdj, uc, conn);
-                List<BO> sbsList = SDK.getBOAPI().query("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE").connection(conn).addQuery("CONTRACT_SERVICE_PERIOD_ID =", ORG_PERIOD_ID).list();
-                if (sbsList != null && sbsList.size() > 0)
-                    for (BO sbs : sbsList) {
-                        BO newSbs = new BO();
-                        newSbs.setAll(sbs.asMap());
-                        newSbs.setId(null);
-                        newSbs.set("CONTRACT_SERVICE_PERIOD_ID", servicePeriodAdj.getId());
-                        SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE", newSbs, uc, conn);
-                    }
+            //服务调整的生效日期,是按照日期顺序创建的
+            if (needDel == false) {
+
+                contractServiceLogger.info("服务调整的生效日期,是按照日期顺序创建的");
+
+                List<BO> servicePeriodList = SDK.getBOAPI().query("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD").connection(conn).addQuery("CONTRACT_SERVICE_ID =", editService.getString("CONTRACT_SERVICE_ID")).orderBy("PERIOD_BEGIN_DATE").asc().list();
 
+                if (servicePeriodList != null && servicePeriodList.size() > 0) {
 
-                //旧的计费周期更新
-                firstServicePeriod.set("PERIOD_END_DATE", EFFECTIVE_DATE.minusDays(1));
-                BigDecimal periodRate = divideToBigDecimal(GetPeriodDays(period_begin_date, EFFECTIVE_DATE.minusDays(1)), GetPeriodDays(period_begin_date, period_end_date));
-                firstServicePeriod.set("PERIOD_PRICE", multiply(firstServicePeriod.get("PERIOD_PRICE"), periodRate));
-                firstServicePeriod.set("PERIOD_COST", multiply(firstServicePeriod.get("PERIOD_COST"), periodRate));
-                firstServicePeriod.set("PERIOD_ADJUSTED_PRICE", firstServicePeriod.get("PERIOD_PRICE"));
-                firstServicePeriod.set("ORG_PERIOD_ID", ORG_PERIOD_ID);
-                SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", firstServicePeriod, conn);
+                    for (BO servicePeriod : servicePeriodList) {
+                        LocalDate period_begin_date = getLocalDate(servicePeriod.get("PERIOD_BEGIN_DATE"));
+                        LocalDate period_end_date = getLocalDate(servicePeriod.get("PERIOD_END_DATE"));
+
+                        //调整日期之前,不用修改
+                        if (period_end_date.isBefore(EFFECTIVE_DATE)) {
+                            continue;
+                        }
+                        //处于调整日期之后的
+                        if (period_begin_date.isBefore(EFFECTIVE_DATE) && !period_end_date.isBefore(EFFECTIVE_DATE)) {
+                            //分成调整前和调整后 两条计费周期
+                            //新的计费周期
+                            BO servicePeriodAdj = new BO();
+                            servicePeriodAdj.setAll(servicePeriod.asMap());
+                            servicePeriodAdj.setId(null);
+                            servicePeriodAdj.set("PERIOD_BEGIN_DATE", EFFECTIVE_DATE);
+                            servicePeriodAdj.set("PERIOD_END_DATE", period_end_date);
+                            servicePeriodAdj.set("QUANTITY", editService.get("QUANTITY"));
+
+                            String ORG_PERIOD_ID = servicePeriod.getString("ORG_PERIOD_ID");
+                            if (StringUtils.isBlank(ORG_PERIOD_ID))
+                                ORG_PERIOD_ID = servicePeriod.getId();
+                            servicePeriodAdj.set("ORG_PERIOD_ID", ORG_PERIOD_ID);
+
+                            BigDecimal periodRateAdj = divideToBigDecimal(GetPeriodDays(EFFECTIVE_DATE, period_end_date), GetPeriodDays(period_begin_date, period_end_date));
+
+                            BigDecimal priceRate = editService.get("TOTAL_PRICE", BigDecimal.class).divide(editService.get("OLD_TOTAL_PRICE", BigDecimal.class), 10, RoundingMode.HALF_UP);
+                            BigDecimal costRate = editService.get("TOTAL_COST", BigDecimal.class).divide(editService.get("OLD_TOTAL_COST", BigDecimal.class), 10, RoundingMode.HALF_UP);
+
+                            servicePeriodAdj.set("PERIOD_PRICE", multiply(servicePeriod.get("PERIOD_PRICE"), multiply(periodRateAdj, priceRate)));
+                            servicePeriodAdj.set("PERIOD_COST", multiply(servicePeriod.get("PERIOD_COST"), multiply(periodRateAdj, costRate)));
+                            servicePeriodAdj.set("PERIOD_ADJUSTED_PRICE", servicePeriodAdj.get("PERIOD_PRICE"));
+                            SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", servicePeriodAdj, uc, conn);
+
+
+                            List<BO> sbsList = SDK.getBOAPI().query("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE").connection(conn).addQuery("CONTRACT_SERVICE_PERIOD_ID =", ORG_PERIOD_ID).list();
+                            if (sbsList != null && sbsList.size() > 0)
+                                for (BO sbs : sbsList) {
+                                    BO newSbs = new BO();
+                                    newSbs.setAll(sbs.asMap());
+                                    newSbs.setId(null);
+                                    newSbs.set("CONTRACT_SERVICE_PERIOD_ID", servicePeriodAdj.getId());
+                                    SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE", newSbs, uc, conn);
+                                }
+
+                            //旧的计费周期更新
+                            servicePeriod.set("PERIOD_END_DATE", EFFECTIVE_DATE.minusDays(1));
+                            BigDecimal periodRate = divideToBigDecimal(GetPeriodDays(period_begin_date, EFFECTIVE_DATE.minusDays(1)), GetPeriodDays(period_begin_date, period_end_date));
+                            servicePeriod.set("PERIOD_PRICE", multiply(servicePeriod.get("PERIOD_PRICE"), periodRate));
+                            servicePeriod.set("PERIOD_COST", multiply(servicePeriod.get("PERIOD_COST"), periodRate));
+                            servicePeriod.set("PERIOD_ADJUSTED_PRICE", servicePeriod.get("PERIOD_PRICE"));
+                            servicePeriod.set("ORG_PERIOD_ID", ORG_PERIOD_ID);
+                            SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", servicePeriod, conn);
+                        } else {
+                            //重新计算
+                            BigDecimal priceRate = editService.get("TOTAL_PRICE", BigDecimal.class).divide(editService.get("OLD_TOTAL_PRICE", BigDecimal.class), 10, RoundingMode.HALF_UP);
+                            BigDecimal costRate = editService.get("TOTAL_COST", BigDecimal.class).divide(editService.get("OLD_TOTAL_COST", BigDecimal.class), 10, RoundingMode.HALF_UP);
+                            servicePeriod.set("QUANTITY", editService.get("QUANTITY"));
+                            servicePeriod.set("PERIOD_PRICE", multiply(servicePeriod.get("PERIOD_PRICE"), priceRate));
+                            servicePeriod.set("PERIOD_COST", multiply(servicePeriod.get("PERIOD_COST"), costRate));
+                            servicePeriod.set("PERIOD_ADJUSTED_PRICE", servicePeriod.get("PERIOD_PRICE"));
+                            SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", servicePeriod, conn);
+                        }
+                    }
+                }
 
-                SATRT_DATE = period_end_date.plusDays(1);
             } else {
+                contractServiceLogger.info("本次服务调整生效日期之后的服务调整全部作废");
+
+                //生效日期之后的
+                List<BO> servicePeriodList = SDK.getBOAPI().query("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD").connection(conn).addQuery("CONTRACT_SERVICE_ID =", editService.getString("CONTRACT_SERVICE_ID")).addQuery("PERIOD_END_DATE >=", EFFECTIVE_DATE_STR).orderBy("PERIOD_BEGIN_DATE").asc().list();
+
+                BO firstServicePeriod = servicePeriodList.get(0);
+                //判断是不是个整周期
+                String ORG_PERIOD_ID = firstServicePeriod.getString("ORG_PERIOD_ID");
+
+                LocalDate SATRT_DATE = null;
+                if (StringUtils.isBlank(ORG_PERIOD_ID)) {
+                    ORG_PERIOD_ID = firstServicePeriod.getString("ORG_PERIOD_ID");
+                    LocalDate period_begin_date = getLocalDate(firstServicePeriod.get("PERIOD_BEGIN_DATE"));
+                    LocalDate period_end_date = getLocalDate(firstServicePeriod.get("PERIOD_END_DATE"));
+
+                    //新的计费周期
+                    BO servicePeriodAdj = new BO();
+
+                    servicePeriodAdj.setAll(firstServicePeriod.asMap());
+                    servicePeriodAdj.setId(null);
+
+                    servicePeriodAdj.set("PERIOD_BEGIN_DATE", EFFECTIVE_DATE);
+                    servicePeriodAdj.set("PERIOD_END_DATE", period_end_date);
+                    servicePeriodAdj.set("QUANTITY", editService.get("QUANTITY"));
+                    servicePeriodAdj.set("ORG_PERIOD_ID", ORG_PERIOD_ID);
+
+                    BigDecimal periodRateAdj = divideToBigDecimal(GetPeriodDays(EFFECTIVE_DATE, period_end_date), GetPeriodDays(period_begin_date, period_end_date));
+
+                    BigDecimal priceRate = editService.get("TOTAL_PRICE", BigDecimal.class).divide(editService.get("OLD_TOTAL_PRICE", BigDecimal.class), 10, RoundingMode.HALF_UP);
+                    BigDecimal costRate = editService.get("TOTAL_COST", BigDecimal.class).divide(editService.get("OLD_TOTAL_COST", BigDecimal.class), 10, RoundingMode.HALF_UP);
+
+                    servicePeriodAdj.set("PERIOD_PRICE", multiply(firstServicePeriod.get("PERIOD_PRICE"), multiply(periodRateAdj, priceRate)));
+                    servicePeriodAdj.set("PERIOD_COST", multiply(firstServicePeriod.get("PERIOD_COST"), multiply(periodRateAdj, costRate)));
+                    servicePeriodAdj.set("PERIOD_ADJUSTED_PRICE", servicePeriodAdj.get("PERIOD_PRICE"));
+                    SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", servicePeriodAdj, uc, conn);
+                    List<BO> sbsList = SDK.getBOAPI().query("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE").connection(conn).addQuery("CONTRACT_SERVICE_PERIOD_ID =", ORG_PERIOD_ID).list();
+                    if (sbsList != null && sbsList.size() > 0)
+                        for (BO sbs : sbsList) {
+                            BO newSbs = new BO();
+                            newSbs.setAll(sbs.asMap());
+                            newSbs.setId(null);
+                            newSbs.set("CONTRACT_SERVICE_PERIOD_ID", servicePeriodAdj.getId());
+                            SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE", newSbs, uc, conn);
+                        }
 
-                LocalDate period_begin_date = getLocalDate(firstServicePeriod.get("PERIOD_BEGIN_DATE"));
-                LocalDate period_end_date = getLocalDate(firstServicePeriod.get("PERIOD_END_DATE"));
-                firstServicePeriod.set("PERIOD_END_DATE", EFFECTIVE_DATE.minusDays(1));
-                BigDecimal periodRate = divideToBigDecimal(GetPeriodDays(period_begin_date, EFFECTIVE_DATE.minusDays(1)), GetPeriodDays(period_begin_date, period_end_date));
-                firstServicePeriod.set("PERIOD_PRICE", multiply(firstServicePeriod.get("PERIOD_PRICE"), periodRate));
-                firstServicePeriod.set("PERIOD_COST", multiply(firstServicePeriod.get("PERIOD_COST"), periodRate));
-                firstServicePeriod.set("PERIOD_ADJUSTED_PRICE", firstServicePeriod.get("PERIOD_PRICE"));
-                firstServicePeriod.set("ORG_PERIOD_ID", ORG_PERIOD_ID);
-                SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", firstServicePeriod, conn);
 
+                    //旧的计费周期更新
+                    firstServicePeriod.set("PERIOD_END_DATE", EFFECTIVE_DATE.minusDays(1));
+                    BigDecimal periodRate = divideToBigDecimal(GetPeriodDays(period_begin_date, EFFECTIVE_DATE.minusDays(1)), GetPeriodDays(period_begin_date, period_end_date));
+                    firstServicePeriod.set("PERIOD_PRICE", multiply(firstServicePeriod.get("PERIOD_PRICE"), periodRate));
+                    firstServicePeriod.set("PERIOD_COST", multiply(firstServicePeriod.get("PERIOD_COST"), periodRate));
+                    firstServicePeriod.set("PERIOD_ADJUSTED_PRICE", firstServicePeriod.get("PERIOD_PRICE"));
+                    firstServicePeriod.set("ORG_PERIOD_ID", ORG_PERIOD_ID);
+                    SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", firstServicePeriod, conn);
 
-                List<BO> servicePeriodList2 = SDK.getBOAPI().query("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD").connection(conn).addQuery("CONTRACT_SERVICE_ID =", editService.getString("CONTRACT_SERVICE_ID")).addQuery("ORG_PERIOD_ID =", ORG_PERIOD_ID).orderBy("PERIOD_BEGIN_DATE").desc().list();
+                    SATRT_DATE = period_end_date.plusDays(1);
+                } else {
 
-                DBSql.update(conn, "DELETE FROM BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE WHERE CONTRACT_SERVICE_PERIOD_ID IN (SELECT ID FROM BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD WHERE ORG_PERIOD_ID=? AND PERIOD_END_DATE>=?)", new Object[]{ORG_PERIOD_ID, EFFECTIVE_DATE_STR});
+                    LocalDate period_begin_date = getLocalDate(firstServicePeriod.get("PERIOD_BEGIN_DATE"));
+                    LocalDate period_end_date = getLocalDate(firstServicePeriod.get("PERIOD_END_DATE"));
+                    firstServicePeriod.set("PERIOD_END_DATE", EFFECTIVE_DATE.minusDays(1));
+                    BigDecimal periodRate = divideToBigDecimal(GetPeriodDays(period_begin_date, EFFECTIVE_DATE.minusDays(1)), GetPeriodDays(period_begin_date, period_end_date));
+                    firstServicePeriod.set("PERIOD_PRICE", multiply(firstServicePeriod.get("PERIOD_PRICE"), periodRate));
+                    firstServicePeriod.set("PERIOD_COST", multiply(firstServicePeriod.get("PERIOD_COST"), periodRate));
+                    firstServicePeriod.set("PERIOD_ADJUSTED_PRICE", firstServicePeriod.get("PERIOD_PRICE"));
+                    firstServicePeriod.set("ORG_PERIOD_ID", ORG_PERIOD_ID);
+                    SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", firstServicePeriod, conn);
 
-                DBSql.update(conn, "DELETE FROM BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD WHERE ORG_PERIOD_ID=? AND PERIOD_END_DATE>=?", new Object[]{ORG_PERIOD_ID, EFFECTIVE_DATE_STR});
 
+                    List<BO> servicePeriodList2 = SDK.getBOAPI().query("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD").connection(conn).addQuery("CONTRACT_SERVICE_ID =", editService.getString("CONTRACT_SERVICE_ID")).addQuery("ORG_PERIOD_ID =", ORG_PERIOD_ID).orderBy("PERIOD_BEGIN_DATE").desc().list();
 
-                BO lastServicePeriod = servicePeriodList2.get(0);
-                LocalDate last_period_begin_date = getLocalDate(lastServicePeriod.get("PERIOD_BEGIN_DATE"));
-                LocalDate last_period_end_date = getLocalDate(lastServicePeriod.get("PERIOD_END_DATE"));
+                    DBSql.update(conn, "DELETE FROM BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE WHERE CONTRACT_SERVICE_PERIOD_ID IN (SELECT ID FROM BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD WHERE ORG_PERIOD_ID=? AND PERIOD_END_DATE>=?)", new Object[]{ORG_PERIOD_ID, EFFECTIVE_DATE_STR});
 
-                //新的计费周期
-                BO servicePeriodAdj = new BO();
+                    DBSql.update(conn, "DELETE FROM BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD WHERE ORG_PERIOD_ID=? AND PERIOD_END_DATE>=?", new Object[]{ORG_PERIOD_ID, EFFECTIVE_DATE_STR});
 
-                servicePeriodAdj.setAll(firstServicePeriod.asMap());
-                servicePeriodAdj.setId(null);
 
-                servicePeriodAdj.set("PERIOD_BEGIN_DATE", EFFECTIVE_DATE);
-                servicePeriodAdj.set("PERIOD_END_DATE", last_period_end_date);
-                servicePeriodAdj.set("QUANTITY", editService.get("QUANTITY"));
-                servicePeriodAdj.set("ORG_PERIOD_ID", ORG_PERIOD_ID);
+                    BO lastServicePeriod = servicePeriodList2.get(0);
+                    LocalDate last_period_begin_date = getLocalDate(lastServicePeriod.get("PERIOD_BEGIN_DATE"));
+                    LocalDate last_period_end_date = getLocalDate(lastServicePeriod.get("PERIOD_END_DATE"));
 
-                LocalDate start = getPreviousPeriodStart(last_period_end_date.plusDays(1), editService.getString("PERIOD_TYPE"));
-                BigDecimal periodRateAdj = divideToBigDecimal(GetPeriodDays(EFFECTIVE_DATE, last_period_end_date), GetPeriodDays(start, last_period_end_date));    // 首周期占整周期比例
-                servicePeriodAdj.set("PERIOD_PRICE", multiply(editService.get("TOTAL_PRICE"), periodRateAdj));
-                servicePeriodAdj.set("PERIOD_COST", multiply(editService.get("TOTAL_COST"), periodRateAdj));
+                    //新的计费周期
+                    BO servicePeriodAdj = new BO();
 
-                servicePeriodAdj.set("PERIOD_ADJUSTED_PRICE", servicePeriodAdj.get("PERIOD_PRICE"));
-                SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", servicePeriodAdj, uc, conn);
+                    servicePeriodAdj.setAll(firstServicePeriod.asMap());
+                    servicePeriodAdj.setId(null);
 
+                    servicePeriodAdj.set("PERIOD_BEGIN_DATE", EFFECTIVE_DATE);
+                    servicePeriodAdj.set("PERIOD_END_DATE", last_period_end_date);
+                    servicePeriodAdj.set("QUANTITY", editService.get("QUANTITY"));
+                    servicePeriodAdj.set("ORG_PERIOD_ID", ORG_PERIOD_ID);
 
-                List<BO> sbsList = SDK.getBOAPI().query("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE").connection(conn).addQuery("CONTRACT_SERVICE_PERIOD_ID =", ORG_PERIOD_ID).list();
-                if (sbsList != null && sbsList.size() > 0)
-                    for (BO sbs : sbsList) {
-                        BO newSbs = new BO();
-                        newSbs.setAll(sbs.asMap());
-                        newSbs.setId(null);
-                        newSbs.set("CONTRACT_SERVICE_PERIOD_ID", servicePeriodAdj.getId());
-                        SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE", newSbs, uc, conn);
-                    }
+                    LocalDate start = getPreviousPeriodStart(last_period_end_date.plusDays(1), editService.getString("PERIOD_TYPE"));
+                    BigDecimal periodRateAdj = divideToBigDecimal(GetPeriodDays(EFFECTIVE_DATE, last_period_end_date), GetPeriodDays(start, last_period_end_date));    // 首周期占整周期比例
+                    servicePeriodAdj.set("PERIOD_PRICE", multiply(editService.get("TOTAL_PRICE"), periodRateAdj));
+                    servicePeriodAdj.set("PERIOD_COST", multiply(editService.get("TOTAL_COST"), periodRateAdj));
+
+                    servicePeriodAdj.set("PERIOD_ADJUSTED_PRICE", servicePeriodAdj.get("PERIOD_PRICE"));
+                    SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", servicePeriodAdj, uc, conn);
 
-                SATRT_DATE = last_period_end_date.plusDays(1);
-            }
 
-            String SATRT_DATE_STR = SATRT_DATE.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
-            //SATRT_DATE 之后,全部删除,重新计算
-            DBSql.update(conn, "DELETE FROM BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE WHERE CONTRACT_SERVICE_PERIOD_ID IN (SELECT ID FROM BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD WHERE CONTRACT_SERVICE_ID=? AND PERIOD_END_DATE>=?)", new Object[]{editService.getString("CONTRACT_SERVICE_ID"), SATRT_DATE_STR});
+                    List<BO> sbsList = SDK.getBOAPI().query("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE").connection(conn).addQuery("CONTRACT_SERVICE_PERIOD_ID =", ORG_PERIOD_ID).list();
+                    if (sbsList != null && sbsList.size() > 0)
+                        for (BO sbs : sbsList) {
+                            BO newSbs = new BO();
+                            newSbs.setAll(sbs.asMap());
+                            newSbs.setId(null);
+                            newSbs.set("CONTRACT_SERVICE_PERIOD_ID", servicePeriodAdj.getId());
+                            SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE", newSbs, uc, conn);
+                        }
 
-            DBSql.update(conn, "DELETE FROM BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD WHERE CONTRACT_SERVICE_ID=? AND PERIOD_END_DATE>=?", new Object[]{editService.getString("CONTRACT_SERVICE_ID"), SATRT_DATE_STR});
+                    SATRT_DATE = last_period_end_date.plusDays(1);
+                }
 
+                String SATRT_DATE_STR = SATRT_DATE.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+                //SATRT_DATE 之后,全部删除,重新计算
+                DBSql.update(conn, "DELETE FROM BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE WHERE CONTRACT_SERVICE_PERIOD_ID IN (SELECT ID FROM BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD WHERE CONTRACT_SERVICE_ID=? AND PERIOD_END_DATE>=?)", new Object[]{editService.getString("CONTRACT_SERVICE_ID"), SATRT_DATE_STR});
 
-            LocalDate END_DATE = getLocalDate(contract.get("END_DATE"));//合同结束日期
-            String maxPeriod = editService.getString("PERIOD_TYPE");
+                DBSql.update(conn, "DELETE FROM BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD WHERE CONTRACT_SERVICE_ID=? AND PERIOD_END_DATE>=?", new Object[]{editService.getString("CONTRACT_SERVICE_ID"), SATRT_DATE_STR});
 
-            //服务包上的服务
-            List<String> sbsList = null;
-            String serviceIds = DBSql.getString("select SERVICE_ID from BO_EU_DNIVT_SERVICE_BUNDLE where ID=?", new Object[]{editService.get("OBJECT_ID")});
-            if (StringUtils.isNotBlank(serviceIds)) {
-                sbsList = Arrays.asList(serviceIds.split(","));
-            }
 
-            //生成服务周期
-            if (SATRT_DATE.isBefore(END_DATE)) {
-                //循环添加全部周期
-                while (!SATRT_DATE.isAfter(END_DATE)) {
+                LocalDate END_DATE = getLocalDate(contract.get("END_DATE"));//合同结束日期
+                String maxPeriod = editService.getString("PERIOD_TYPE");
 
-                    BigDecimal periodRate = BigDecimal.ONE;
-                    LocalDate periodEnd = getNextPeriodStart(SATRT_DATE, maxPeriod).minusDays(1);//本周期结束时间
-                    if (periodEnd.isAfter(END_DATE)) {//如果结束日期大于合同结束日期,则计算结束日期和合同结束日期的差值,并计算该差值占整周期的比例
-                        periodRate = divideToBigDecimal(GetPeriodDays(SATRT_DATE, END_DATE), GetPeriodDays(SATRT_DATE, periodEnd));
-                        periodEnd = END_DATE;
-                    }
+                //服务包上的服务
+                List<String> sbsList = null;
+                String serviceIds = DBSql.getString("select SERVICE_ID from BO_EU_DNIVT_SERVICE_BUNDLE where ID=?", new Object[]{editService.get("OBJECT_ID")});
+                if (StringUtils.isNotBlank(serviceIds)) {
+                    sbsList = Arrays.asList(serviceIds.split(","));
+                }
+
+                //生成服务周期
+                if (SATRT_DATE.isBefore(END_DATE)) {
+                    //循环添加全部周期
+                    while (!SATRT_DATE.isAfter(END_DATE)) {
 
-                    BO csp = new BO();//服务周期
-
-                    csp.setAll(firstServicePeriod.asMap());
-                    csp.set("PERIOD_BEGIN_DATE", SATRT_DATE);
-                    csp.set("PERIOD_END_DATE", periodEnd);
-                    csp.set("QUANTITY", editService.get("QUANTITY"));
-
-                    BigDecimal period_price = multiply(editService.get("UNIT_PRICE"), editService.get("QUANTITY"));
-                    period_price = periodRate.multiply(period_price);
-                    csp.set("PERIOD_PRICE", period_price);
-                    contractServiceLogger.info("计算-csp-PERIOD_COST");
-                    BigDecimal period_cost = multiply(editService.get("UNIT_COST"), editService.get("QUANTITY"));
-                    period_cost = periodRate.multiply(period_cost);
-                    csp.set("PERIOD_COST", period_cost);
-                    csp.set("PERIOD_ADJUSTED_PRICE", csp.get("PERIOD_PRICE"));
-                    SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", csp, uc, conn);
-
-                    if (editService.getString("OBJECT_TYPE").equals("2"))//服务包
-                    {
-                        //本周期成本
-                        String prorated_cost_change = DBSql.getString(conn, "select UNIT_COST from BO_EU_DNIVT_SERVICE where ID=?", new Object[]{editService.getString("OBJECT_ID")});//供应商账号
-                        if (sbsList != null) {
-                            for (String sbs : sbsList) {
-                                BO cspbs = new BO();
-                                cspbs.set("CONTRACT_SERVICE_PERIOD_ID", csp.getId());
-                                cspbs.set("SERVICE_ID", sbs);
-                                cspbs.set("VENDOR_ACCOUNT_ID", csp.get("VENDOR_ACCOUNT_ID"));
-                                cspbs.set("PERIOD_COST", prorated_cost_change);
-                                cspbs.setBindId(csp.getString("BINDID"));
-                                SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE", cspbs, uc, conn);
+                        BigDecimal periodRate = BigDecimal.ONE;
+                        LocalDate periodEnd = getNextPeriodStart(SATRT_DATE, maxPeriod).minusDays(1);//本周期结束时间
+                        if (periodEnd.isAfter(END_DATE)) {//如果结束日期大于合同结束日期,则计算结束日期和合同结束日期的差值,并计算该差值占整周期的比例
+                            periodRate = divideToBigDecimal(GetPeriodDays(SATRT_DATE, END_DATE), GetPeriodDays(SATRT_DATE, periodEnd));
+                            periodEnd = END_DATE;
+                        }
+
+                        BO csp = new BO();//服务周期
+
+                        csp.setAll(firstServicePeriod.asMap());
+                        csp.set("PERIOD_BEGIN_DATE", SATRT_DATE);
+                        csp.set("PERIOD_END_DATE", periodEnd);
+                        csp.set("QUANTITY", editService.get("QUANTITY"));
+
+                        BigDecimal period_price = multiply(editService.get("UNIT_PRICE"), editService.get("QUANTITY"));
+                        period_price = periodRate.multiply(period_price);
+                        csp.set("PERIOD_PRICE", period_price);
+                        contractServiceLogger.info("计算-csp-PERIOD_COST");
+                        BigDecimal period_cost = multiply(editService.get("UNIT_COST"), editService.get("QUANTITY"));
+                        period_cost = periodRate.multiply(period_cost);
+                        csp.set("PERIOD_COST", period_cost);
+                        csp.set("PERIOD_ADJUSTED_PRICE", csp.get("PERIOD_PRICE"));
+                        SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", csp, uc, conn);
+
+                        if (editService.getString("OBJECT_TYPE").equals("2"))//服务包
+                        {
+                            //本周期成本
+                            String prorated_cost_change = DBSql.getString(conn, "select UNIT_COST from BO_EU_DNIVT_SERVICE where ID=?", new Object[]{editService.getString("OBJECT_ID")});//供应商账号
+                            if (sbsList != null) {
+                                for (String sbs : sbsList) {
+                                    BO cspbs = new BO();
+                                    cspbs.set("CONTRACT_SERVICE_PERIOD_ID", csp.getId());
+                                    cspbs.set("SERVICE_ID", sbs);
+                                    cspbs.set("VENDOR_ACCOUNT_ID", csp.get("VENDOR_ACCOUNT_ID"));
+                                    cspbs.set("PERIOD_COST", prorated_cost_change);
+                                    cspbs.setBindId(csp.getString("BINDID"));
+                                    SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE", cspbs, uc, conn);
+                                }
                             }
                         }
-                    }
-                    if (periodEnd != null) {
-                        SATRT_DATE = periodEnd.plusDays(1);
+                        if (periodEnd != null) {
+                            SATRT_DATE = periodEnd.plusDays(1);
+                        }
                     }
                 }
-            }
 
-            String PERIOD = editService.getString("PERIOD");//服务起止日期
-            String ADJUST_PERIOD = editService.getString("ADJUST_PERIOD");//服务调整的起止日期
-            LocalDate PERIOD_END;
-            if (StringUtils.isNotBlank(PERIOD)) {
-                PERIOD_END = getLocalDate(PERIOD.split("~")[1]);
-                PERIOD = PERIOD.split("~")[0] + "~" + LocalDateYYYYMMDD(END_DATE);
-            } else {
-                PERIOD_END = getLocalDate(ADJUST_PERIOD.split("~")[1]);
-                ADJUST_PERIOD = ADJUST_PERIOD.split("~")[0] + "~" + LocalDateYYYYMMDD(END_DATE);
-            }
+                String PERIOD = editService.getString("PERIOD");//服务起止日期
+                String ADJUST_PERIOD = editService.getString("ADJUST_PERIOD");//服务调整的起止日期
+                LocalDate PERIOD_END;
+                if (StringUtils.isNotBlank(PERIOD)) {
+                    PERIOD_END = getLocalDate(PERIOD.split("~")[1]);
+                    PERIOD = PERIOD.split("~")[0] + "~" + LocalDateYYYYMMDD(END_DATE);
+                } else {
+                    PERIOD_END = getLocalDate(ADJUST_PERIOD.split("~")[1]);
+                    ADJUST_PERIOD = ADJUST_PERIOD.split("~")[0] + "~" + LocalDateYYYYMMDD(END_DATE);
+                }
 
-            //缩短
-            if (PERIOD_END.isAfter(END_DATE)) {
-                if (StringUtils.isNotBlank(ADJUST_PERIOD)) {
-                    LocalDate ADJUST_PERIOD_END = getLocalDate(ADJUST_PERIOD.split("~")[1]);
-                    if (ADJUST_PERIOD_END.isAfter(END_DATE)) {
-                        PERIOD = null;
-                        ADJUST_PERIOD = ADJUST_PERIOD.split("~")[0] + "~" + LocalDateYYYYMMDD(END_DATE);
+                //缩短
+                if (PERIOD_END.isAfter(END_DATE)) {
+                    if (StringUtils.isNotBlank(ADJUST_PERIOD)) {
+                        LocalDate ADJUST_PERIOD_END = getLocalDate(ADJUST_PERIOD.split("~")[1]);
+                        if (ADJUST_PERIOD_END.isAfter(END_DATE)) {
+                            PERIOD = null;
+                            ADJUST_PERIOD = ADJUST_PERIOD.split("~")[0] + "~" + LocalDateYYYYMMDD(END_DATE);
+                        }
                     }
                 }
+                DBSql.update(conn, "update BO_EU_DNCTT_CONTRACT_SERVICE set PERIOD=?,ADJUST_PERIOD=? where ID=? and BINDID=?", new Object[]{PERIOD, ADJUST_PERIOD, editService.get("CONTRACT_SERVICE_ID"), editService.get("BINDID")});
             }
-            DBSql.update(conn, "update BO_EU_DNCTT_CONTRACT_SERVICE set PERIOD=?,ADJUST_PERIOD=? where ID=? and BINDID=?", new Object[]{PERIOD, ADJUST_PERIOD, editService.get("CONTRACT_SERVICE_ID"), editService.get("BINDID")});
         }
-
         editService.set("IS_EFFECTIVE", "已执行");
         SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_SERVICE_EDIT", editService, conn);
 
         //如果在此次调整之后还有调整,则设为失效状态
-
         BO contractServiceBO = SDK.getBOAPI().get("BO_EU_DNCTT_CONTRACT_SERVICE", editService.getString("CONTRACT_SERVICE_ID"));
         contractServiceBO.set("OLD_QUANTITY", editService.get("OLD_QUANTITY"));
         contractServiceBO.set("OLD_UNIT_PRICE", editService.get("OLD_UNIT_PRICE"));
@@ -1330,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