HULEI 4 месяцев назад
Родитель
Сommit
d3f675952d

+ 0 - 0
.gitignore


BIN
com.awspaas.user.apps.donenow_ctt/lib/com.awspaas.user.apps.donenow_ctt.jar


+ 536 - 0
com.awspaas.user.apps.donenow_ctt/src/com/awspaas/user/apps/donenow_ctt/controller/contractApproveController.java

@@ -14,10 +14,17 @@ import com.awspaas.user.apps.donenow_ctt.service.contractService;
 import org.apache.commons.lang3.StringUtils;
 
 import java.sql.SQLException;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import static com.awspaas.user.apps.donenow_ctt.service.contractService.GetEntryCost;
+import static com.awspaas.user.apps.donenow_ctt.service.contractService.getLocalDate;
+
 @Controller
 public class contractApproveController {
     private static final Logger contractLogger = SDK.getLogAPI().getLogger(contractApproveController.class);//记录日志
@@ -247,4 +254,533 @@ public class contractApproveController {
         return ResponseObject.newOkResponse();
     }
 
+
+    /**
+     * 工时审批
+     * @param uc
+     * @param approveDate
+     * @param approveIds
+     * @return
+     */
+    @Mapping("com.awspaas.user.apps.donenow_ctt.approve_labor")
+    public ResponseObject laborApprove(UserContext uc, String approveDate, String approveIds) {
+        String[] IdArr = approveIds.split(",");
+        String sql = "SELECT * FROM VIEW_EU_DNV_PENDING_LABOR WHERE ID IN(";
+        for (int i = 0; IdArr.length > i; i++) {
+            sql += "?,";
+        }
+        sql = sql.substring(0, sql.length() - 1) + ")";
+        List<RowMap> list = DBSql.getMaps(sql, Arrays.stream(IdArr).toArray());
+
+        for (RowMap rowMap : list) {
+            String COST_CODE_ID = getString(rowMap, "COST_CODE_ID");//获取成本代码ID
+            RowMap thisTaxCate = null;//税收种类
+            if (StringUtils.isNotBlank(COST_CODE_ID)) {
+                RowMap costCode = DBSql.getMap("SELECT * FROM BO_EU_DND_COST_CODE WHERE ID=?", new Object[]{COST_CODE_ID});
+                if (costCode != null && StringUtils.isNotBlank(costCode.getString("TAX_CATEGORY_ID"))) {
+                    thisTaxCate = DBSql.getMap("SELECT * FROM BO_EU_DND_GENERAL WHERE OID=?", new Object[]{costCode.getString("TAX_CATEGORY_ID")});
+                }
+            }
+
+            RowMap thisContract = null;//合同
+            RowMap thisAccount = null;
+            String CONTRRACT_ID = getString(rowMap, "CONTRACT_ID");
+
+            if (StringUtils.isNotBlank(CONTRRACT_ID)) {
+                thisContract = DBSql.getMap("SELECT * FROM BO_EU_DNCTT_CONTRACT WHERE ID=?", new Object[]{CONTRRACT_ID});
+
+                RowMap thatAccount = DBSql.getMap("SELECT * FROM BO_EU_DNCRM_ACCOUNT WHERE ID IN (SELECT ACCOUNT_ID FROM BO_EU_DNCTT_CONTRACT WHERE ID=?)", new Object[]{CONTRRACT_ID});
+                if (thatAccount != null)
+                    thisAccount = thatAccount;
+            }
+
+            RowMap thisProject = null;
+
+            RowMap thisTaxRegion = null;
+            Double tax_rate = 0.0;//税率
+
+            String TASK_ID = rowMap.getString("TASK_ID");
+            if (StringUtils.isNotBlank(TASK_ID)) {
+
+                thisProject = DBSql.getMap("SELECT * FROM BO_EU_DNPRO_PROJECT WHERE ID IN (SELECT PROJECT_ID FROM BO_EU_DNSDK_TASK WHERE ID=?)", new Object[]{TASK_ID});
+
+                RowMap thatAccount = DBSql.getMap("SELECT * FROM BO_EU_DNCRM_ACCOUNT WHERE ID IN (SELECT ACCOUNT_ID FROM BO_EU_DNSDK_TASK WHERE ID=?)", new Object[]{TASK_ID});
+                if (thatAccount != null)
+                    thisAccount = thatAccount;
+            }
+
+            //该员工的费率
+            // decimal? laborRate = sweDal.FindSignleBySql<decimal?>($"SELECT f_get_labor_rate({thisContractId},{oldEntry.cost_code_id},{oldEntry.role_id});");
+
+            String thisContractId = thisContract == null ? "null" : thisContract.getString("ID");
+            String ROLE_ID = rowMap.getString("ROLE_ID");
+
+            Double laborRate = 0.0;
+            //该员工的费率
+            try {
+                laborRate = DBSql.getDouble("SELECT f_get_labor_rate(" + thisContractId + "," + COST_CODE_ID + "," + ROLE_ID + "," + uc.getCompanyModel().getId() + ") as laborRate", "laborRate");
+            } catch (Exception e) {
+                System.out.println("获取费率异常" + e.getMessage());
+            }
+
+            // 获取税收信息
+            if (thisAccount != null && StringUtils.isNotBlank(thisAccount.getString("TAX_REGION_ID"))) {
+                thisTaxRegion = DBSql.getMap("SELECT * FROM BO_EU_DND_GENERAL WHERE OID=?", new Object[]{thisAccount.getString("TAX_REGION_ID")});
+            }
+            if (thisTaxCate != null && thisTaxRegion != null) {
+
+                RowMap thisTax = DBSql.getMap("SELECT * FROM BO_EU_DND_TAX_REGION_CATE WHERE TAX_REGION_ID=? AND TAX_CATEGORY_ID=?", new Object[]{thisTaxRegion.getString("ID"), thisTaxCate.getString("ID")});
+                if (thisTax != null) {
+                    tax_rate = thisTax.getDouble("TOTAL_EFFECTIVE_TAX_RATE");
+                }
+            }
+
+            LocalDate thisDate = getLocalDate(approveDate);//审批时间
+            Double block_hour_multiplier = 0.0;
+            if (thisContract != null && StringUtils.isNotBlank(ROLE_ID)) {
+                //var thisConRole = new ctt_contract_rate_dal(_connect).GetSinRate(thisContract.id, (long)oldEntry.role_id);
+                //return FindSignleBySql<ctt_contract_rate>($"SELECT * from ctt_contract_rate where delete_time = 0 and contract_id = {contract_id} and //role_id ={role_id}");
+                RowMap thisConRole = DBSql.getMap("SELECT * FROM BO_EU_DNCTT_CONTRACT_RATE WHERE CONTRACT_ID=? AND ROLE_ID=?", new Object[]{thisContract.getString("ID"), ROLE_ID});
+
+                if (thisConRole != null) {
+                    block_hour_multiplier = thisConRole.getDouble("BLOCK_HOUR_MULTIPLIER");//乘数
+                } else {
+                    RowMap thisRole = DBSql.getMap("SELECT * FROM BO_EU_DNSYS_ROLE WHERE ID=?", new Object[]{ROLE_ID});
+                    if (thisRole != null) {
+                        block_hour_multiplier = thisRole.getDouble("HOURLY_FACTOR");//角色时间系数
+                    }
+                }
+            }
+
+            Map<String, Double> block = new HashMap<>();//存储预付id,和总价
+            Map<String, Double> blockRate = new HashMap<>();//存储预付id,和总价
+
+            RowMap thisWorkEntry = DBSql.getMap("select * from BO_EU_DNSDK_WORK_ENTRY where ID=?", new Object[]{getString(rowMap, "ID")});
+            LocalDate thisEntryDate = getLocalDate(getString(thisWorkEntry, "START_TIME"));
+            LocalDate thisEntryEndDate = StringUtils.isBlank(getString(thisWorkEntry, "START_TIME")) ? thisEntryDate : getLocalDate(getString(thisWorkEntry, "END_TIME"));
+
+            LocalDate thisContractStartDate = thisContract == null ? null : thisContract.getDate("START_DATE").toInstant()
+                    .atZone(ZoneId.systemDefault())
+                    .toLocalDate();
+            LocalDate thisContractEndDate = thisContract == null ? null : thisContract.getDate("END_DATE").toInstant()
+                    .atZone(ZoneId.systemDefault())
+                    .toLocalDate();
+
+            Double totalHours = StringUtils.isBlank(thisWorkEntry.getString("HOURS_BILLED_DEDUCTION")) ? thisWorkEntry.getDouble("HOURS_BILLED") : thisWorkEntry.getDouble("HOURS_BILLED_DEDUCTION");
+            if (thisContract != null && thisEntryDate != null && thisContractStartDate.compareTo(thisEntryDate) <= 0 && thisContractEndDate.compareTo(thisEntryEndDate) >= 0) {
+
+                String endDate = thisEntryDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+
+                // 这个工时的总额
+                Double totalMoney = StringUtils.isBlank(thisWorkEntry.getString("HOURS_BILLED_DEDUCTION")) ? thisWorkEntry.getDouble("HOURS_BILLED") : thisWorkEntry.getDouble("HOURS_BILLED_DEDUCTION");
+                totalMoney = totalMoney * (StringUtils.isBlank(thisWorkEntry.getString("HOURS_RATE_DEDUCTION")) ? laborRate : thisWorkEntry.getDouble("HOURS_RATE_DEDUCTION"));
+
+                //不计费的工时
+                if (laborRate == null || laborRate <= 0) {
+                    BO thisBlockDed = new BO();
+                    thisBlockDed.set("TYPE_ID", "1318");//工时
+                    thisBlockDed.set("OBJECT_ID", thisWorkEntry.getString("ID"));
+                    thisBlockDed.set("POSTED_DATE", thisDate);
+                    thisBlockDed.set("TASK_ID", thisWorkEntry.getString("TASK_ID"));
+                    thisBlockDed.set("ACCOUNT_ID", thisAccount.getString("ID"));
+                    thisBlockDed.set("QUANTITY", totalHours);
+                    thisBlockDed.set("BILL_CREATE_USER_ID", thisWorkEntry.getString("CREATEUSER"));
+                    thisBlockDed.set("PURCHASE_ORDER_NO", thisWorkEntry.getString("PURCHASE_ORDER_NO"));
+                    thisBlockDed.set("TAX_CATEGORY_NAME", thisTaxCate == null ? null : thisTaxCate.getString("NAME"));
+                    thisBlockDed.set("TAX_REGION_NAME", thisTaxRegion == null ? null : thisTaxRegion.getString("NAME"));
+                    thisBlockDed.set("EFFECTIVE_TAX_RATE", tax_rate);
+                    thisBlockDed.set("ROLE_ID", thisWorkEntry.getString("ROLE_ID"));
+                    thisBlockDed.set("EXTENDED_COST", GetEntryCost(thisWorkEntry.getString("ID")));
+                    thisBlockDed.set("CONTRACT_ID", thisWorkEntry.getString("CONTRACT_ID"));
+                    if (thisTaxCate != null)
+                        thisBlockDed.set("TAX_CATEGORY_ID", thisTaxCate.getString("ID"));
+
+                    thisBlockDed.set("EXTENDED_PRICE", 0);
+                    thisBlockDed.set("BILL_ACCOUNT_ID", thisWorkEntry.get("BILL_ACCOUNT_ID"));
+
+                    dn.recordFormChanges.record(uc, thisBlockDed, "审批提交工时");
+                    SDK.getBOAPI().createDataBO("BO_EU_DNCRM_ACCOUNT_DEDUCTION", thisBlockDed, uc);
+                } else if (thisContract != null && thisContract.getString("TYPE_ID").equals("1203")) {
+                    //预付费合同
+
+                    //获取工时
+                    Double extended_price = DBSql.getDouble("SELECT sum(round(b.rate/" + laborRate + " - ifnull((SELECT sum(extended_price)FROM bo_eu_dncrm_account_deduction WHERE contract_block_id = b.id ),0),2)) AS RATE FROM bo_eu_dnctt_contract_block b WHERE b.contract_id='" + thisContract.getString("ID") + "' and b.status_id=1 and b.start_date <='" + thisEntryDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + "' and b.end_date >='" + endDate + "'", "RATE");
+                    extended_price = extended_price * laborRate;
+
+                    //  Double thisEntryRate = GetRateByCodeAndRole(COST_CODE_ID, ROLE_ID);
+
+                    List<RowMap> block_hours = DBSql.getMaps("SELECT b.ID,(round(b.rate/" + laborRate + " - ifnull((SELECT sum(extended_price)FROM bo_eu_dncrm_account_deduction WHERE contract_block_id = b.id ),0),2)) AS RATE FROM bo_eu_dnctt_contract_block b WHERE b.contract_id='" + thisContract.getString("ID") + "' and b.status_id=1 and b.start_date <='" + thisEntryDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + "' and b.end_date >='" + endDate + "'");
+
+                    for (RowMap block_hour : block_hours) {
+                        if (block_hour.get("RATE") != null && block_hour.getDouble("RATE") > 0) {
+                            block.put(block_hour.getString("ID"), block_hour.getDouble("RATE"));
+                        }
+                        blockRate.put(block_hour.getString("ID"), block_hour.getDouble("RATE"));
+                    }
+
+                    if (totalMoney == null || totalMoney <= extended_price) {
+                        if (totalMoney != null) {
+                            Double extend = 0.0;
+                            for (String key : block.keySet()) {
+                                extend += block.get(key);
+                                if (extend <= totalMoney) {
+                                    BO thisBlockDed = new BO();
+                                    thisBlockDed.set("TYPE_ID", "1318");
+                                    thisBlockDed.set("OBJECT_ID", thisWorkEntry.getString("ID"));
+                                    thisBlockDed.set("POSTED_DATE", thisDate);
+                                    thisBlockDed.set("TASK_ID", thisWorkEntry.getString("TASK_ID"));
+                                    thisBlockDed.set("EXTENDED_PRICE", block.get(key));
+                                    thisBlockDed.set("ACCOUNT_ID", thisWorkEntry.getString("ACCOUNT_ID"));
+                                    thisBlockDed.set("CONTRACT_ID", thisWorkEntry.getString("CONTRACT_ID"));
+                                    thisBlockDed.set("BILL_CREATE_USER_ID", thisWorkEntry.getString("CREATEUSER"));
+                                    thisBlockDed.set("PURCHASE_ORDER_NO", thisWorkEntry.getString("PURCHASE_ORDER_NO"));
+                                    thisBlockDed.set("TAX_CATEGORY_NAME", thisTaxCate == null ? null : thisTaxCate.getString("NAME"));
+                                    thisBlockDed.set("TAX_REGION_NAME", thisTaxRegion == null ? null : thisTaxRegion.getString("NAME"));
+                                    thisBlockDed.set("EFFECTIVE_TAX_RATE", tax_rate);
+                                    thisBlockDed.set("ROLE_ID", thisWorkEntry.getString("ROLE_ID"));
+                                    thisBlockDed.set("QUANTITY", totalHours);
+                                    thisBlockDed.set("RATE", blockRate.get(key));
+                                    thisBlockDed.set("CONTRACT_BLOCK_ID", key);
+                                    thisBlockDed.set("BLOCK_HOUR_MULTIPLIER", block_hour_multiplier);
+                                    thisBlockDed.set("EXTENDED_COST", GetEntryCost(thisWorkEntry.getString("ID")));
+
+                                    if (thisTaxCate != null)
+                                        thisBlockDed.set("TAX_CATEGORY_ID", thisTaxCate.getString("ID"));
+
+
+                                    if (thisAccount.getString("IS_TAX_EXEMPT").equals("1") == false) {
+                                        thisBlockDed.set("TAX_DOLLARS", thisWorkEntry.getDouble("HOURS_BILLED") * laborRate * (1 - 1 / (1 + tax_rate)));
+                                    }
+                                    if (thisWorkEntry.getString("IS_BILLABLE").equals("0"))
+                                        thisBlockDed.set("EXTENDED_PRICE", 0);
+                                    dn.recordFormChanges.record(uc, thisBlockDed, "审批提交工时");
+                                    SDK.getBOAPI().createDataBO("BO_EU_DNCRM_ACCOUNT_DEDUCTION", thisBlockDed, uc);
+
+                                    //修改相应的预付费信息
+                                    BO thisBlock = SDK.getBOAPI().get("BO_EU_DNCTT_CONTRACT_BLOCK", key);
+                                    if (thisBlock != null) {
+                                        thisBlock.set("STATUS_ID", 0);
+                                        dn.recordFormChanges.record(uc, thisBlock, "修改预付费信息");
+                                        SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_BLOCK", thisBlock);
+                                    }
+                                    if (extend == totalMoney) {
+                                        break;
+                                    }
+
+
+                                } else {
+                                    BO thisBlockDed = new BO();
+                                    thisBlockDed.set("TYPE_ID", "1318");
+                                    thisBlockDed.set("OBJECT_ID", thisWorkEntry.getString("ID"));
+                                    thisBlockDed.set("POSTED_DATE", thisDate);
+                                    thisBlockDed.set("TASK_ID", thisWorkEntry.getString("TASK_ID"));
+                                    thisBlockDed.set("EXTENDED_PRICE", block.get(key));
+                                    thisBlockDed.set("ACCOUNT_ID", thisWorkEntry.getString("ACCOUNT_ID"));
+                                    thisBlockDed.set("CONTRACT_ID", thisWorkEntry.getString("CONTRACT_ID"));
+                                    thisBlockDed.set("BILL_CREATE_USER_ID", thisWorkEntry.getString("CREATEUSER"));
+                                    thisBlockDed.set("PURCHASE_ORDER_NO", thisWorkEntry.getString("PURCHASE_ORDER_NO"));
+                                    thisBlockDed.set("TAX_CATEGORY_NAME", thisTaxCate == null ? null : thisTaxCate.getString("NAME"));
+                                    thisBlockDed.set("TAX_REGION_NAME", thisTaxRegion == null ? null : thisTaxRegion.getString("NAME"));
+                                    thisBlockDed.set("EFFECTIVE_TAX_RATE", tax_rate);
+                                    thisBlockDed.set("ROLE_ID", thisWorkEntry.getString("ROLE_ID"));
+                                    thisBlockDed.set("QUANTITY", totalHours);
+                                    thisBlockDed.set("RATE", blockRate.get(key));
+                                    thisBlockDed.set("CONTRACT_BLOCK_ID", key);
+                                    thisBlockDed.set("BLOCK_HOUR_MULTIPLIER", block_hour_multiplier);
+                                    thisBlockDed.set("EXTENDED_COST", GetEntryCost(thisWorkEntry.getString("ID")));
+                                    if (thisTaxCate != null)
+                                        thisBlockDed.set("TAX_CATEGORY_ID", thisTaxCate.getString("ID"));
+
+                                    thisBlockDed.set("extended_price", block.get(key) - (extend - totalMoney));
+                                    if (thisWorkEntry.getString("IS_BILLABLE").equals("0"))
+                                        thisBlockDed.set("EXTENDED_PRICE", 0);
+                                    dn.recordFormChanges.record(uc, thisBlockDed, "审批提交工时");
+                                    SDK.getBOAPI().createDataBO("BO_EU_DNCRM_ACCOUNT_DEDUCTION", thisBlockDed, uc);
+                                    break;
+                                }
+                            }
+                        } else {
+
+                            BO thisBlockDed = new BO();
+                            thisBlockDed.set("TYPE_ID", "1318");
+                            thisBlockDed.set("OBJECT_ID", thisWorkEntry.getString("ID"));
+                            thisBlockDed.set("POSTED_DATE", thisDate);
+                            thisBlockDed.set("TASK_ID", thisWorkEntry.getString("TASK_ID"));
+                            thisBlockDed.set("ACCOUNT_ID", thisWorkEntry.getString("ACCOUNT_ID"));
+                            thisBlockDed.set("CONTRACT_ID", thisWorkEntry.getString("CONTRACT_ID"));
+                            thisBlockDed.set("BILL_CREATE_USER_ID", thisWorkEntry.getString("CREATEUSER"));
+                            thisBlockDed.set("PURCHASE_ORDER_NO", thisWorkEntry.getString("PURCHASE_ORDER_NO"));
+                            thisBlockDed.set("TAX_CATEGORY_NAME", thisTaxCate == null ? null : thisTaxCate.getString("NAME"));
+                            thisBlockDed.set("TAX_REGION_NAME", thisTaxRegion == null ? null : thisTaxRegion.getString("NAME"));
+                            thisBlockDed.set("EFFECTIVE_TAX_RATE", tax_rate);
+                            thisBlockDed.set("ROLE_ID", thisWorkEntry.getString("ROLE_ID"));
+                            thisBlockDed.set("QUANTITY", totalHours);
+                            thisBlockDed.set("RATE", thisWorkEntry.get("HOURS_RATE_DEDUCTION") != null ? thisWorkEntry.get("HOURS_RATE_DEDUCTION") : laborRate);
+                            thisBlockDed.set("BLOCK_HOUR_MULTIPLIER", block_hour_multiplier);
+                            thisBlockDed.set("EXTENDED_COST", GetEntryCost(thisWorkEntry.getString("ID")));
+                            if (thisTaxCate != null)
+                                thisBlockDed.set("TAX_CATEGORY_ID", thisTaxCate.getString("ID"));
+                            if (thisWorkEntry.getString("IS_BILLABLE").equals("0"))
+                                thisBlockDed.set("EXTENDED_PRICE", 0);
+                            dn.recordFormChanges.record(uc, thisBlockDed, "审批提交工时");
+                            SDK.getBOAPI().createDataBO("BO_EU_DNCRM_ACCOUNT_DEDUCTION", thisBlockDed, uc);
+                        }
+                    } else {
+                        RowMap ccnr = DBSql.getMap("select * from BO_EU_DNCTT_CONTRACT_NOTIFY_RULE where contract_id=?", new Object[]{thisContractId});
+                        if (ccnr != null && ccnr.get("RATE") != null && ccnr.getDouble("RATE") > 0) {
+                            Double extend = 0.0;
+                            for (String key : block.keySet()) {
+                                extend = extend + block.get(key);
+                                BO thisBlockDed = new BO();
+                                thisBlockDed.set("TYPE_ID", "1318");
+                                thisBlockDed.set("OBJECT_ID", thisWorkEntry.getString("ID"));
+                                thisBlockDed.set("POSTED_DATE", thisDate);
+                                thisBlockDed.set("TASK_ID", thisWorkEntry.getString("TASK_ID"));
+                                thisBlockDed.set("EXTENDED_PRICE", block.get(key));
+                                thisBlockDed.set("ACCOUNT_ID", thisWorkEntry.getString("ACCOUNT_ID"));
+                                thisBlockDed.set("CONTRACT_ID", thisWorkEntry.getString("CONTRACT_ID"));
+                                thisBlockDed.set("BILL_CREATE_USER_ID", thisWorkEntry.getString("CREATEUSER"));
+                                thisBlockDed.set("PURCHASE_ORDER_NO", thisWorkEntry.getString("PURCHASE_ORDER_NO"));
+                                thisBlockDed.set("TAX_CATEGORY_NAME", thisTaxCate == null ? null : thisTaxCate.getString("NAME"));
+                                thisBlockDed.set("TAX_REGION_NAME", thisTaxRegion == null ? null : thisTaxRegion.getString("NAME"));
+                                thisBlockDed.set("EFFECTIVE_TAX_RATE", tax_rate);
+                                thisBlockDed.set("ROLE_ID", thisWorkEntry.getString("ROLE_ID"));
+                                thisBlockDed.set("QUANTITY", totalHours);
+                                thisBlockDed.set("RATE", blockRate.get(key));
+                                thisBlockDed.set("CONTRACT_BLOCK_ID", key);
+                                thisBlockDed.set("BLOCK_HOUR_MULTIPLIER", block_hour_multiplier);
+                                thisBlockDed.set("EXTENDED_COST", GetEntryCost(thisWorkEntry.getString("ID")));
+                                if (thisTaxCate != null)
+                                    thisBlockDed.set("TAX_CATEGORY_ID", thisTaxCate.getString("ID"));
+
+                                if (thisWorkEntry.getString("IS_BILLABLE").equals("0"))
+                                    thisBlockDed.set("EXTENDED_PRICE", 0);
+
+                                if (thisAccount.getString("IS_TAX_EXEMPT").equals("1") == false)
+                                    thisBlockDed.set("TAX_DOLLARS", thisWorkEntry.getDouble("HOURS_BILLED") * laborRate * (1 - 1 / (1 + tax_rate)));
+
+                                dn.recordFormChanges.record(uc, thisBlockDed, "审批提交工时");
+                                SDK.getBOAPI().createDataBO("BO_EU_DNCRM_ACCOUNT_DEDUCTION", thisBlockDed, uc);
+
+                                //修改相应的预付费信息
+                                BO thisBlock = SDK.getBOAPI().get("BO_EU_DNCTT_CONTRACT_BLOCK", key);
+                                if (thisBlock != null) {
+                                    thisBlock.set("STATUS_ID", 0);
+                                    dn.recordFormChanges.record(uc, thisBlock, "修改合同成本预付时间或费用");
+                                    SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_BLOCK", thisBlock);
+                                }
+                            }
+
+                            if (extend - totalMoney <= 0) {
+                                //???  什么逻辑
+                                System.out.println("合同金额不足");
+                                System.out.println("后面怎么处理。。。。。。。。");
+                            }
+
+
+                        } else {
+                            BO thisDed = new BO();
+                            thisDed.set("TYPE_ID", "1318");
+                            thisDed.set("OBJECT_ID", thisWorkEntry.getString("ID"));
+                            thisDed.set("POSTED_DATE", thisDate);
+                            thisDed.set("TASK_ID", thisWorkEntry.getString("TASK_ID"));
+                            thisDed.set("EXTENDED_PRICE", thisWorkEntry.getDouble("HOURS_BILLED") * laborRate * block_hour_multiplier);
+                            thisDed.set("ACCOUNT_ID", thisAccount.getString("ID"));
+                            thisDed.set("CONTRACT_ID", thisWorkEntry.getString("CONTRACT_ID"));
+                            thisDed.set("QUANTITY", thisWorkEntry.getDouble("HOURS_BILLED"));
+                            thisDed.set("PURCHASE_ORDER_NO", thisWorkEntry.getString("PURCHASE_ORDER_NO"));
+                            thisDed.set("BILL_ACCOUNT_ID", thisWorkEntry.getString("BILL_ACCOUNT_ID"));
+                            thisDed.set("TAX_CATEGORY_NAME", thisTaxCate == null ? null : thisTaxCate.getString("NAME"));
+                            thisDed.set("TAX_REGION_NAME", thisTaxRegion == null ? null : thisTaxRegion.getString("NAME"));
+                            thisDed.set("EFFECTIVE_TAX_RATE", tax_rate);
+                            thisDed.set("ROLE_ID", thisWorkEntry.getString("ROLE_ID"));
+                            thisDed.set("QUANTITY", totalHours);
+                            thisDed.set("RATE", thisWorkEntry.get("HOURS_RATE_DEDUCTION") != null ? thisWorkEntry.get("HOURS_RATE_DEDUCTION") : laborRate);
+                            thisDed.set("BLOCK_HOUR_MULTIPLIER", block_hour_multiplier);
+                            thisDed.set("EXTENDED_COST", GetEntryCost(thisWorkEntry.getString("ID")));
+                            if (thisTaxCate != null)
+                                thisDed.set("TAX_CATEGORY_ID", thisTaxCate.getString("ID"));
+
+                            if (thisWorkEntry.getString("IS_BILLABLE").equals("0"))
+                                thisDed.set("EXTENDED_PRICE", 0);
+
+                            if (thisAccount.getString("IS_TAX_EXEMPT").equals("1") == false)
+                                thisDed.set("TAX_DOLLARS", thisWorkEntry.getDouble("HOURS_BILLED") * laborRate * (1 - 1 / (1 + tax_rate)));
+
+                            dn.recordFormChanges.record(uc, thisDed, "审批提交工时");
+                            SDK.getBOAPI().createDataBO("BO_EU_DNCRM_ACCOUNT_DEDUCTION", thisDed, uc);
+                        }
+                    }
+                }
+            }
+
+            if (thisContract == null || (thisContract.getString("type_id").equals("1203") == false && thisContract.getString("TYPE_ID").equals("1202") == false) || thisContractStartDate.compareTo(thisEntryDate) > 0 || thisContractEndDate.compareTo(thisEntryEndDate) < 0) {
+                BO thisDed = new BO();
+                thisDed.set("TYPE_ID", "1318");
+                thisDed.set("OBJECT_ID", thisWorkEntry.getString("ID"));
+                thisDed.set("POSTED_DATE", thisDate);
+                thisDed.set("TASK_ID", thisWorkEntry.getString("TASK_ID"));
+                thisDed.set("EXTENDED_PRICE", thisWorkEntry.getDouble("HOURS_BILLED") * laborRate * block_hour_multiplier);
+                thisDed.set("ACCOUNT_ID", thisAccount == null ? null : thisAccount.getString("ID"));
+                thisDed.set("CONTRACT_ID", thisWorkEntry.getString("CONTRACT_ID"));
+                thisDed.set("QUANTITY", thisWorkEntry.getDouble("HOURS_BILLED"));
+                thisDed.set("PURCHASE_ORDER_NO", thisWorkEntry.getString("PURCHASE_ORDER_NO"));
+                thisDed.set("BILL_ACCOUNT_ID", thisWorkEntry.getString("BILL_ACCOUNT_ID"));
+                thisDed.set("TAX_CATEGORY_NAME", thisTaxCate == null ? null : thisTaxCate.getString("NAME"));
+                thisDed.set("TAX_REGION_NAME", thisTaxRegion == null ? null : thisTaxRegion.getString("NAME"));
+                thisDed.set("EFFECTIVE_TAX_RATE", tax_rate);
+                thisDed.set("ROLE_ID", thisWorkEntry.getString("ROLE_ID"));
+                thisDed.set("QUANTITY", totalHours);
+                thisDed.set("RATE", thisWorkEntry.get("HOURS_RATE_DEDUCTION") != null ? thisWorkEntry.get("HOURS_RATE_DEDUCTION") : laborRate);
+                thisDed.set("BLOCK_HOUR_MULTIPLIER", block_hour_multiplier);
+                thisDed.set("EXTENDED_COST", GetEntryCost(thisWorkEntry.getString("ID")));
+                if (thisTaxCate != null)
+                    thisDed.set("TAX_CATEGORY_ID", thisTaxCate.getString("ID"));
+
+                if (thisWorkEntry.getString("IS_BILLABLE").equals("0"))
+                    thisDed.set("EXTENDED_PRICE", 0);
+
+                if (thisAccount.getString("IS_TAX_EXEMPT").equals("1") == false)
+                    thisDed.set("TAX_DOLLARS", thisWorkEntry.getDouble("HOURS_BILLED") * laborRate * (1 - 1 / (1 + tax_rate)));
+
+                dn.recordFormChanges.record(uc, thisDed, "审批提交工时");
+                SDK.getBOAPI().createDataBO("BO_EU_DNCRM_ACCOUNT_DEDUCTION", thisDed, uc);
+            }
+
+
+            BO oldEntry = SDK.getBOAPI().get("BO_EU_DNSDK_WORK_ENTRY", thisWorkEntry.getString("ID"));
+            oldEntry.set("APPROVE_AND_POST_DATE", thisDate);
+            oldEntry.set("APPROVE_AND_POST_USER_ID", uc.getUID());
+            dn.recordFormChanges.record(uc, oldEntry, "审批提交工时");
+            SDK.getBOAPI().update("BO_EU_DNSDK_WORK_ENTRY", oldEntry);
+
+            //通知
+            // 待完善
+
+        }
+
+        return ResponseObject.newOkResponse();
+    }
+
+    /**
+     * 获取字段值
+     * @param rowMap
+     * @param key
+     * @return
+     */
+    private String getString(RowMap rowMap, String key) {
+        if (rowMap.containsKey(key))
+            return rowMap.getString(key);
+        else if (rowMap.containsKey(key.toUpperCase()))
+            return rowMap.getString(rowMap.getString(key.toUpperCase()));
+        else if (rowMap.containsKey(key.toLowerCase()))
+            return rowMap.getString(rowMap.getString(key.toLowerCase()));
+
+        key = key.toUpperCase();
+        for (String s : rowMap.keySet()) {
+            if (s.toUpperCase().equals(key))
+                return rowMap.getString(s);
+        }
+        return null;
+    }
+
+
+    /**
+     * 费用审批
+     * @param uc
+     * @param approveDate
+     * @param approveIds
+     * @return
+     */
+    @Mapping("com.awspaas.user.apps.donenow_ctt.approve_expense")
+    public ResponseObject expenseApprove(UserContext uc, String approveDate, String approveIds) {
+        String[] IdArr = approveIds.split(",");
+        String sql = "SELECT * FROM VIEW_EU_DNV_PENDING_EXPENSE WHERE ID IN(";
+        for (int i = 0; IdArr.length > i; i++) {
+            sql += "?,";
+        }
+        sql = sql.substring(0, sql.length() - 1) + ")";
+        List<RowMap> list = DBSql.getMaps(sql, Arrays.stream(IdArr).toArray());
+        for (RowMap rowMap : list) {
+            String expenseId = getString(rowMap, "ID");
+            RowMap oldExp = DBSql.getMap("SELECT * FROM BO_EU_DNSDK_EXPENSE WHERE ID=?", expenseId);
+            RowMap thisTaxCate = null;//税收种类
+            RowMap thisTaxRegion = null;//税区
+            Double tax_rate = 0.0;//税率
+            String contract_id = null;
+
+            if (StringUtils.isNotBlank("COST_CODE_ID")) {
+                RowMap thisCost = DBSql.getMap("SELECT * FROM BO_EU_DND_COST_CODE WHERE ID=?", getString(rowMap, "COST_CODE_ID"));
+                if (thisCost != null && StringUtils.isNotBlank(thisCost.getString("TAX_CATEGORY_ID"))) {
+                    thisTaxCate = DBSql.getMap("SELECT * FROM BO_EU_DND_GENERAL WHERE OID=?", thisCost.getString("TAX_CATEGORY_ID"));
+                }
+            }
+            RowMap thisAccount = DBSql.getMap("SELECT * FROM BO_EU_DNCRM_ACCOUNT WHERE ID=?", getString(rowMap, "ACCOUNT_ID"));
+            if (thisAccount != null && StringUtils.isNotBlank(thisAccount.getString("TAX_REGION_ID"))) {
+                thisTaxRegion = DBSql.getMap("SELECT * FROM BO_EU_DND_GENERAL WHERE OID=?", thisAccount.getString("TAX_REGION_ID"));
+            }
+            if (thisTaxRegion != null && thisTaxCate != null) {
+                tax_rate = DBSql.getDouble("SELECT TOTAL_EFFECTIVE_TAX_RATE FROM BO_EU_DND_TAX_REGION_CATE WHERE tax_region_id='" + thisTaxRegion.getString("ID") + "' and tax_cate_id='" + thisTaxCate.getString("ID") + "' ", "TOTAL_EFFECTIVE_TAX_RATE");
+            }
+            LocalDate thisDate = getLocalDate(approveDate);//审批时间
+
+            if (StringUtils.isNotBlank(oldExp.getString("PROJECT_ID"))) {
+                String projectRateContractId = DBSql.getString("SELECT CONTRACT_ID FROM BO_EU_DNPRO_PROJECT WHERE ID=?", new Object[]{oldExp.getString("PROJECT_ID")});
+                if (StringUtils.isNotBlank(projectRateContractId)) {
+                    contract_id = projectRateContractId;
+                }
+            }
+
+            if (StringUtils.isNotBlank(oldExp.getString("TASK_ID"))) {
+                String taskRateContractId = DBSql.getString("SELECT CONTRACT_ID FROM BO_EU_DNSDK_TASK WHERE ID=?", new Object[]{oldExp.getString("TASK_ID")});
+                if (StringUtils.isNotBlank(taskRateContractId)) {
+                    contract_id = taskRateContractId;
+                }
+            }
+
+
+            Double extended_price = 0.0;
+            if (oldExp.getString("IS_BILLABLE").equals("1")) {
+                if (oldExp.get("AMOUNT_DEDUCTION") != null && oldExp.getDouble("AMOUNT_DEDUCTION") > 0) {
+                    extended_price = oldExp.getDouble("AMOUNT_DEDUCTION");
+                } else if (oldExp.get("AMOUNT") != null && oldExp.getDouble("AMOUNT") > 0) {
+                    extended_price = oldExp.getDouble("AMOUNT");
+                }
+            }
+
+            BO thisDed = new BO();
+            thisDed.set("CONTRACT_ID", contract_id);
+            thisDed.set("OBJECT_ID", oldExp.getString("ID"));
+            thisDed.set("TYPE_ID", "1322");
+            thisDed.set("POSTED_DATE", thisDate);
+            thisDed.set("TASK_ID", oldExp.getString("TASK_ID"));
+            thisDed.set("EXTENDED_PRICE", extended_price);
+            thisDed.set("EXTENDED_COST", extended_price);
+            thisDed.set("ACCOUNT_ID", oldExp.getString("ACCOUNT_ID"));
+            thisDed.set("QUANTITY", 1);
+            thisDed.set("BILL_CREATE_USER_ID", oldExp.getString("CREATEUSER"));
+            thisDed.set("PURCHASE_ORDER_NO", oldExp.getString("PURCHASE_ORDER_NO"));
+            thisDed.set("TAX_CATEGORY_NAME", thisTaxCate == null ? null : thisTaxCate.getString("NAME"));
+            thisDed.set("TAX_REGION_NAME", thisTaxRegion == null ? null : thisTaxRegion.getString("NAME"));
+            thisDed.set("EFFECTIVE_TAX_RATE", tax_rate);
+            thisDed.set("TAX_DOLLARS", extended_price * (1 - 1 / (1 + tax_rate)));
+            if (thisTaxCate != null)
+                thisDed.set("TAX_CATEGORY_ID", thisTaxCate.getString("ID"));
+
+            dn.recordFormChanges.record(uc, thisDed, "审批提交费用");
+            SDK.getBOAPI().createDataBO("BO_EU_DNCRM_ACCOUNT_DEDUCTION", thisDed, uc);
+
+            BO oldExpense = SDK.getBOAPI().get("BO_EU_DNSDK_EXPENSE", oldExp.getString("ID"));
+            oldExpense.set("APPROVE_AND_POST_DATE", thisDate);
+            oldExpense.set("APPROVE_AND_POST_USER_ID", uc.getUID());
+            dn.recordFormChanges.record(uc, oldExpense, "审批提交费用");
+            SDK.getBOAPI().update("BO_EU_DNSDK_EXPENSE", oldExpense);
+
+
+            //通知
+        }
+
+
+        return ResponseObject.newOkResponse();
+    }
 }

+ 7 - 4
com.awspaas.user.apps.donenow_ctt/src/com/awspaas/user/apps/donenow_ctt/controller/contractCostController.java

@@ -49,9 +49,11 @@ public class contractCostController {
         int warehouseProductAvailableQuantity = ObjToInt(DBSql.getString("SELECT SUM(AVAILABLE) FROM VIEW_EU_DNINVT_PRODUCT_INVENTORY where ID=?", new Object[]{warehouseProductId}));
         logger.info("可用库存数量:" + warehouseProductAvailableQuantity);
 
-        if (warehouseProductAvailableQuantity <= 0) return ResponseObject.newErrResponse("库存数量不足");
+        if (warehouseProductAvailableQuantity <= 0)
+            return ResponseObject.newErrResponse("库存数量不足");
 
-        if (warehouseProductQuantity <= 0) return ResponseObject.newErrResponse("库存数量不足");
+        if (warehouseProductQuantity <= 0)
+            return ResponseObject.newErrResponse("库存数量不足");
 
         if (warehouseProductAvailableQuantity <= warehouseProductQuantity)//可用库存数量
             warehouseProductQuantity = warehouseProductAvailableQuantity;
@@ -69,7 +71,8 @@ public class contractCostController {
         newBO.setBindId(processInstance.getId());
         int quantity = contractCostQuantity - contractProductPickQuantity;//待拣货数量
 
-        if (quantity <= 0) return ResponseObject.newErrResponse("无需拣货");
+        if (quantity <= 0) return
+                ResponseObject.newErrResponse("无需拣货");
 
         if (quantity > warehouseProductQuantity) {
             newBO.set("PICK_QUANTITY", warehouseProductQuantity);
@@ -200,7 +203,7 @@ public class contractCostController {
 
         String OUT_RULE = DBSql.getString("SELECT OUT_RULE FROM BO_EU_DNIVT_PRODUCT WHERE ID=?", new Object[]{stockMap.getString("PRODUCT_ID")});
         //1031 FIFO先进先出  1032 LIFO后进先出
-        List<RowMap> lotList = DBSql.getMaps("SELECT b.* FROM bo_eu_dnivt_warehouse_product a JOIN BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT b ON a.BINDID=b.BINDID WHERE b.QUANTITY>0 AND a.ID=? ORDER BY b.CREATEDATE " + (OUT_RULE.equals("1032") ? "DESC" : "ASC"), new Object[]{warehouseProductId});
+        List<RowMap> lotList = DBSql.getMaps("SELECT b.* FROM bo_eu_dnivt_warehouse_product a JOIN BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT b ON a.BINDID=b.BINDID WHERE b.QUANTITY>0 AND a.ID=? ORDER BY b.CREATEDATE " + (OUT_RULE!=null&&OUT_RULE.equals("1032") ? "DESC" : "ASC"), new Object[]{warehouseProductId});
 
         //已被拣货数量
         List<RowMap> pickList = DBSql.getMaps("SELECT a.* from BO_EU_DNCTT_CONTRACT_COST_PRODUCT a JOIN BO_EU_DNCTT_CONTRACT_COST b ON a.CONTRACT_COST_ID=b.ID WHERE a.WAREHOUSE_ID=? AND b.PRODUCT_ID=?", new Object[]{stockMap.getString("WAREHOUSE_ID"), stockMap.getString("PRODUCT_ID")});

+ 25 - 5
com.awspaas.user.apps.donenow_ctt/src/com/awspaas/user/apps/donenow_ctt/controller/contractCreateController.java

@@ -231,13 +231,33 @@ public class contractCreateController {
     public ResponseObject deleteContractService(UserContext uc, String serviceIds) {
         String[] costIdArr = serviceIds.split(",");
 
-
-        String delSql = "DELETE FROM BO_EU_DNCTT_CONTRACT_SERVICE WHERE ID IN(";
+        String selSql = "DELETE FROM BO_EU_DNCTT_CONTRACT_SERVICE WHERE ID IN(";
         for (int i = 0; costIdArr.length > i; i++) {
-            delSql += "?,";
+            selSql += "?,";
         }
-        delSql = delSql.substring(0, delSql.length() - 1) + ")";
-        DBSql.update(delSql, Arrays.stream(costIdArr).toArray());
+        selSql = selSql.substring(0, selSql.length() - 1) + ")";
+        List<RowMap> serviceList = DBSql.getMaps(selSql, Arrays.stream(costIdArr).toArray());
+        for (RowMap service : serviceList) {
+            //删除关联的服务调整
+            List<String> csaIdList = DBSql.getList("select ID from BO_EU_DNCTT_CONTRACT_SERVICE_ADJUST where CONTRACT_ID=? and CONTRACT_SERVICE_ID=?", String.class, new Object[]{service.get("CONTRACT_ID"), service.get("ID")});
+
+            for (String csaId : csaIdList) {
+                DBSql.update("delete from BO_EU_DNCTT_CONTRACT_SERVICE_ADJUST_BUNDLE_SERVICE where CONTRACT_SERVICE_ADJUST_ID=? ", new Object[]{csaId});
+            }
+
+            DBSql.update("delete from BO_EU_DNCTT_CONTRACT_SERVICE_ADJUST where  CONTRACT_ID=? and CONTRACT_SERVICE_ID=?", new Object[]{service.get("CONTRACT_ID"), service.get("ID")});
+
+            //删除关联的服务周期
+            List<String> cspIdList = DBSql.getList("select ID from BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD where  CONTRACT_ID=? and OBJECT_ID=? and CONTRACT_SERVICE_ID=?", String.class, new Object[]{service.get("CONTRACT_ID"), service.get("OBJECT_ID"), service.get("ID")});
+            for (String cspId : cspIdList) {
+                DBSql.update("delete from BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE where CONTRACT_SERVICE_PERIOD_ID=? ", new Object[]{cspId});
+            }
+            DBSql.update("delete from BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD where CONTRACT_ID=? and OBJECT_ID=? and CONTRACT_SERVICE_ID=?", new Object[]{service.get("CONTRACT_ID"), service.get("OBJECT_ID"), service.get("ID")});
+
+
+            DBSql.update("delete from BO_EU_DNCTT_CONTRACT_SERVICE where CONTRACT_ID=? and OBJECT_ID=? and ID=?", new Object[]{service.get("CONTRACT_ID"), service.get("OBJECT_ID"), service.get("ID")});
+        }
+
 
         return ResponseObject.newOkResponse();
     }

+ 1 - 1
com.awspaas.user.apps.donenow_ctt/src/com/awspaas/user/apps/donenow_ctt/event/costPickFormBeforeSave.java

@@ -57,7 +57,7 @@ public class costPickFormBeforeSave extends InterruptListener {
         if (PICK_QUANTITY <= 0)
             throw new BPMNError("pickError3", "拣货数量不能小于0");
 
-        if (snCnt != PICK_QUANTITY) {
+        if (snCnt > 0 && snCnt != PICK_QUANTITY) {
             //拣货数量和序列号个数不一致
             if (DBSql.getString("SELECT IS_SERIALIZED FROM BO_EU_DNIVT_PRODUCT WHERE ID=?", new Object[]{formData.getString("PRODUCT_ID")}).equals("1")) {
                 throw new BPMNError("pickError4", "请填写序列号");

+ 59 - 2
com.awspaas.user.apps.donenow_ctt/src/com/awspaas/user/apps/donenow_ctt/service/contractService.java

@@ -499,7 +499,7 @@ public class contractService {
             BigDecimal periodRate = divideToBigDecimal(GetPeriodDays(EFFECTIVE_DATE, end), GetPeriodDays(start, periodEnd));    // 首周期占整周期比例
             BO csa = new BO();//合同服务调整
             csa.set("CONTRACT_ID", contract.get("ID"));
-            csa.set("OBJECT_ID", service.get("ID"));
+            csa.set("OBJECT_ID", service.get("OBJECT_ID"));
             csa.set("OBJECT_TYPE", service.get("OBJECT_TYPE"));
             csa.set("QUANTITY_CHANGE", service.get("QUANTITY"));
             csa.set("CONTRACT_SERVICE_ID", service.get("ID"));
@@ -657,6 +657,7 @@ public class contractService {
                             Map<String, String> contractCost = new HashMap<String, String>();
                             contractCost.put("ID", contractCostId);
                             contractCost.put("SERVICE_ID", service.getString("ID"));
+                            contractCost.put("SERVICE_NAME", service.getString("NAME"));
                             contractCost.put("serviceID", serviceID);
                             contractCost.put("CONTRACT_ID", contract.getString("ID"));
                             contractCost.put("QUANTITY", service.getString("QUANTITY"));
@@ -678,6 +679,7 @@ public class contractService {
                         Map<String, String> contractCost = new HashMap<String, String>();
                         contractCost.put("ID", contractCostId);
                         contractCost.put("SERVICE_ID", service.getString("ID"));
+                        contractCost.put("SERVICE_NAME", service.getString("NAME"));
                         contractCost.put("serviceID", service.getString("OBJECT_ID"));
                         contractCost.put("CONTRACT_ID", contract.getString("ID"));
                         contractCost.put("QUANTITY", service.getString("QUANTITY"));
@@ -729,6 +731,7 @@ public class contractService {
         contractCost.set("CONTRACT_ID", service.get("CONTRACT_ID"));
         contractCost.set("SERVICE_ID", service.get("SERVICE_ID"));
         contractCost.set("QUANTITY", service.get("QUANTITY"));
+        contractCost.set("NAME", service.get("SERVICE_NAME"));
 
         contractCost.set("PRODUCT_ID", DBSql.getString(conn, "select PRODUCT_ID from BO_EU_DNIVT_SERVICE where ID=?", new Object[]{service.get("serviceID")}));
 
@@ -736,7 +739,7 @@ public class contractService {
             BO product = SDK.getBOAPI().get("BO_EU_DNIVT_PRODUCT", contractCost.getString("PRODUCT_ID"));
 
             if (product != null) {
-                contractCost.set("NAME", product.getString("NAME"));
+
                 contractCost.set("DESCRIPTION", product.getString("DESCRIPTION"));
                 contractCost.set("COST_CODE_ID", product.getString("COST_CODE_ID"));
                 contractCost.set("UNIT_COST", product.getString("UNIT_COST"));
@@ -1281,6 +1284,7 @@ public class contractService {
                         cad.set("TAX_DOLLARS", tax_dollars);
                     }
 
+                    dn.recordFormChanges.record(uc, cad, "审批提交里程碑");
                     SDK.getBOAPI().createDataBO("BO_EU_DNCRM_ACCOUNT_DEDUCTION", cad, uc, connUpdate);
 
                 }
@@ -1537,4 +1541,57 @@ public class contractService {
         return null;
     }
 
+
+    /**
+     * 根据 物料计费代码Id 和 角色ID返回相关费率
+     * @param cost_code_id
+     * @param role_id
+     * @return
+     */
+    public static Double GetRateByCodeAndRole(String cost_code_id, String role_id) {
+        Double rate = null;
+
+        RowMap thisCostCode = DBSql.getMap("SELECT * FROM BO_EU_DND_COST_CODE WHERE ID=?", new Object[]{cost_code_id});
+        RowMap thisRole = DBSql.getMap("SELECT * FROM BO_EU_DNSYS_ROLE WHERE ID=?", new Object[]{role_id});
+        if (thisCostCode != null && thisRole != null) {
+            switch (thisCostCode.getString("BILLING_METHOD_ID")) {
+                case "2166":
+                    rate = thisRole.getDouble("hourly_rate");
+                    break;
+                case "2167":
+                    if (StringUtils.isNotBlank(thisCostCode.getString("RATE_ADJUSTMENT"))) {
+                        rate = (thisRole.getDouble("hourly_rate") + thisCostCode.getDouble("RATE_ADJUSTMENT"));
+                    }
+                    break;
+                case "2168":
+                    if (StringUtils.isNotBlank(thisCostCode.getString("RATE_MULTIPLIER"))) {
+                        rate = (thisRole.getDouble("hourly_rate") * thisCostCode.getDouble("RATE_MULTIPLIER"));
+                    }
+                    break;
+                case "2169":
+                    if (StringUtils.isNotBlank(thisCostCode.getString("CUSTOM_RATE"))) {
+                        rate = thisCostCode.getDouble("CUSTOM_RATE");
+                    }
+                    break;
+                case "2170":
+                    if (StringUtils.isNotBlank(thisCostCode.getString("FLAT_RATE"))) {
+                        rate = thisCostCode.getDouble("FLAT_RATE");
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+        return rate;
+    }
+
+    /**
+     * 获取工时成本
+     * @param id
+     * @return
+     */
+    public static Double GetEntryCost(String id) {
+        return DBSql.getDouble("SELECT( IFNULL(( SELECT rate FROM BO_EU_DNCTT_CONTRACT_INTERNAL_COST WHERE contract_id = p.contract_id AND resource_id = p.resource_id AND role_id = p.role_id LIMIT 1), ( SELECT hourly_rate FROM bo_eu_dnsys_resource_internal_cost WHERE resource_id = p.resource_id AND IFNULL(start_date, '1970-01-01') <= FROM_UNIXTIME(p.start_time / 1000) AND IFNULL(end_date, '9999-01-01') > FROM_UNIXTIME(p.start_time / 1000)) ) * p.hours_billed ) AS COST FROM bo_eu_dnsdk_work_entry p JOIN bo_eu_dnd_cost_code cc ON p.cost_code_id = cc.id JOIN bo_eu_dnsdk_task t ON p.task_id = t.id LEFT JOIN bo_eu_dnctt_contract c ON p.contract_id = c.id WHERE p.id = '" + id + "'", "COST");
+    }
+
 }

+ 1 - 1
com.awspaas.user.apps.donenow_ivt/com.awspaas.user.apps.donenow_ivt.iml

@@ -5,7 +5,7 @@
     <content url="file://$MODULE_DIR$">
       <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
     </content>
-    <orderEntry type="inheritedJdk" />
+    <orderEntry type="jdk" jdkName="temurin-11" jdkType="JavaSDK" />
     <orderEntry type="sourceFolder" forTests="false" />
     <orderEntry type="library" name="aws_lib" level="project" />
   </component>

BIN
com.awspaas.user.apps.donenow_ivt/lib/com.awspaas.user.apps.donenow_ivt.jar


+ 213 - 0
com.awspaas.user.apps.donenow_ivt/src/com/awspaas/user/apps/donenow_ivt/controller/caiController.java

@@ -0,0 +1,213 @@
+package com.awspaas.user.apps.donenow_ivt.controller;
+
+import com.actionsoft.bpms.bpmn.engine.model.run.delegate.ProcessInstance;
+import com.actionsoft.bpms.commons.mvc.view.ResponseObject;
+import com.actionsoft.bpms.server.bind.annotation.Controller;
+import com.actionsoft.bpms.server.bind.annotation.Mapping;
+import com.actionsoft.bpms.server.UserContext;
+import com.actionsoft.bpms.util.DBSql;
+import com.actionsoft.sdk.local.SDK;
+import org.apache.commons.lang3.StringUtils;
+import com.actionsoft.bpms.commons.database.RowMap;
+import com.actionsoft.bpms.bo.engine.BO;
+
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.*;
+import java.util.*;
+
+@Controller
+public class caiController {
+
+    @Mapping(value = "com.awspaas.user.apps.donenow_ivt.queryCai")
+    public ResponseObject queryOrderByOrderId(UserContext uc, String orderId) {
+
+        if (StringUtils.isBlank(orderId)) {
+            return ResponseObject.newErrResponse("订单ID不能为空");
+        }
+
+
+        String sql = "select UNIT_COST_ADD_TAX, ORDER_ID from bo_eu_dnivt_order_product where ORDER_ID = ?";
+        RowMap map = DBSql.getMap(sql, new Object[]{orderId});
+
+
+        if (map == null) {
+            return ResponseObject.newErrResponse("未找到ORDER_ID为【" + orderId + "】的采购项");
+        }
+
+        Map<String, Object> result = new HashMap<>();
+        result.put("UNIT_COST_ADD_TAX", map.getString("UNIT_COST_ADD_TAX"));
+        result.put("ORDER_ID", map.getString("ORDER_ID"));
+
+        ResponseObject responseObject = ResponseObject.newOkResponse();
+        responseObject.setData(result);
+
+        return responseObject;
+    }
+    @Mapping(value = "com.awspaas.user.apps.donenow_ivt.queryCount")
+    public ResponseObject queryPurchaseItemCount(UserContext uc, String orderId) {
+        if (StringUtils.isBlank(orderId)) {
+            return ResponseObject.newErrResponse("订单ID不能为空");
+        }
+
+        String sql = "select count(*) as item_count from bo_eu_dnivt_order_product where ORDER_ID = ?";
+        int itemCount = DBSql.getInt(sql, new Object[]{orderId});
+
+        Map<String, Object> result = new HashMap<>();
+        result.put("orderId", orderId);
+        result.put("itemCount", itemCount);
+        result.put("isSingleItem", itemCount == 1);
+
+        ResponseObject responseObject = ResponseObject.newOkResponse();
+        responseObject.setData(result);
+
+        return responseObject;
+    }
+    @Mapping(value = "com.awspaas.user.apps.donenow_ivt.queryPaymentPlan")
+    public ResponseObject queryPaymentPlan(UserContext uc, String orderId) {
+        if (StringUtils.isBlank(orderId)) {
+            return ResponseObject.newErrResponse("订单ID不能为空");
+        }
+
+        String sql = "select a.order_id 采购订单id ,b.PERIOD_END_DATE 计划付款时间, b.PERIOD_COST 计划付款金额 " +
+                "from `BO_EU_DNIVT_ORDER_PRODUCT` a " +
+                "join `BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD` b " +
+                "on a.CONTRACT_SERVICE_ID = b.CONTRACT_SERVICE_ID " +
+                "where a.ORDER_ID = ?";
+        List<RowMap> rowMaps = DBSql.getMaps(sql, new Object[]{orderId});
+
+        List<Map<String, Object>> resultList = new ArrayList<>();
+        if (rowMaps != null && !rowMaps.isEmpty()) {
+            for (RowMap row : rowMaps) {
+                Map<String, Object> plan = new HashMap<>();
+                plan.put("order_id", orderId);
+                plan.put("计划付款时间", row.getString("计划付款时间"));
+                plan.put("计划付款金额", row.getDouble("计划付款金额"));
+                resultList.add(plan);
+            }
+        } else {
+            ResponseObject responseObject = ResponseObject.newOkResponse();
+            responseObject.put("message", "未找到ORDER_ID为【" + orderId + "】的计划付款信息,可尝试新建");
+            responseObject.setData(Collections.emptyList());
+            return responseObject;
+        }
+
+        ResponseObject responseObject = ResponseObject.newOkResponse();
+        responseObject.setData(resultList);
+        return responseObject;
+    }
+
+    @Mapping(value = "com.awspaas.user.apps.donenow_ivt.queryPayAmount")
+    public ResponseObject queryPayAmount(UserContext uc, String orderId) {
+        if (StringUtils.isBlank(orderId)) {
+            return ResponseObject.newErrResponse("订单ID不能为空");
+        }
+
+        String sql = "select " +
+                "ORDER_ID 采购订单id, " +
+                "PAY_AMOUNT 实际付款金额 " +
+                "from `BO_EU_DNIVT_ORDER_PAYMENT_PLAN` " +
+                "where ORDER_ID = ?";
+        List<RowMap> rowMaps = DBSql.getMaps(sql, new Object[]{orderId});
+
+        List<Map<String, Object>> resultList = new ArrayList<>();
+        if (rowMaps != null && !rowMaps.isEmpty()) {
+            for (RowMap row : rowMaps) {
+                Map<String, Object> amountInfo = new HashMap<>();
+                amountInfo.put("order_id", orderId);
+                amountInfo.put("实际付款金额", row.getDouble("实际付款金额"));
+                resultList.add(amountInfo);
+            }
+        } else {
+            ResponseObject responseObject = ResponseObject.newOkResponse();
+            responseObject.put("message", "未找到ORDER_ID为【" + orderId + "】的实际金额信息,可尝试新建");
+            responseObject.setData(Collections.emptyList());
+            return responseObject;
+        }
+
+        ResponseObject responseObject = ResponseObject.newOkResponse();
+        responseObject.setData(resultList);
+        return responseObject;
+    }
+
+    @Mapping(value = "com.awspaas.user.apps.donenow_ivt.deleteUnpaidPaymentPlan")
+    public ResponseObject deleteUnpaidPaymentPlan(UserContext uc, String orderId) {
+        if (StringUtils.isBlank(orderId)) {
+            return ResponseObject.newErrResponse("订单ID不能为空");
+        }
+
+        String sql = "delete from `BO_EU_DNIVT_ORDER_PAYMENT_PLAN` " +
+                "where ORDER_ID = ? " +
+                "and (PAY_AMOUNT is null or PAY_AMOUNT = 0)";
+        int deletedRows = DBSql.update(sql, new Object[]{orderId});
+
+        if (deletedRows <= 0) {
+            ResponseObject responseObject = ResponseObject.newOkResponse();
+            responseObject.put("message", "未找到ORDER_ID为【" + orderId + "】的删除信息,可尝试新建");
+            responseObject.setData(Collections.emptyList());
+        }
+
+        List<Map<String, Object>> resultList = new ArrayList<>();
+        Map<String, Object> deleteInfo = new HashMap<>();
+        deleteInfo.put("order_id", orderId);
+        deleteInfo.put("删除记录数", deletedRows);
+        resultList.add(deleteInfo);
+
+        ResponseObject responseObject = ResponseObject.newOkResponse();
+        responseObject.setData(resultList);
+
+        return responseObject;
+    }
+
+
+    @Mapping(value = "com.awspaas.user.apps.donenow_ivt.createPaymentPlan")
+    public ResponseObject createPaymentPlan(UserContext uc,
+                                            String orderId,
+                                            String planDate,
+                                            Double planAmount) {
+        if (StringUtils.isBlank(orderId)) {
+            return ResponseObject.newErrResponse("订单ID不能为空");
+        }
+        if (StringUtils.isBlank(planDate)) {
+            return ResponseObject.newErrResponse("计划付款时间不能为空");
+        }
+
+        try {
+            ProcessInstance processInstance = SDK.getProcessAPI()
+                    .createProcessInstance("obj_5cb4ae4a42944fd0a9a284ff4c64c65d",
+                            uc.getUID(),
+                            "付款计划");
+
+            BO bo = new BO();
+
+            bo.setBindId(processInstance.getId());
+
+            bo.set("ORDER_ID", orderId);
+            bo.set("PLAN_DATE", planDate);
+            bo.set("PLAN_AMOUNT", planAmount);
+
+            SDK.getBOAPI().createDataBO("BO_EU_DNIVT_ORDER_PAYMENT_PLAN", bo, uc);
+
+            List<Map<String, Object>> resultList = new ArrayList<>();
+            Map<String, Object> plan = new HashMap<>();
+            plan.put("order_id", orderId);
+            plan.put("计划付款时间", planDate);
+            plan.put("计划付款金额", planAmount);
+            plan.put("bindId", processInstance.getId());
+            resultList.add(plan);
+
+            ResponseObject responseObject = ResponseObject.newOkResponse();
+            responseObject.setData(resultList);
+
+            return responseObject;
+        } catch (Exception e) {
+            return ResponseObject.newErrResponse("创建失败:" + e.getMessage());
+        }
+    }
+
+
+
+
+
+}

+ 12 - 0
com.awspaas.user.apps.donenow_tst/com.awspaas.user.apps.donenow_tst.iml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$/src">
+      <sourceFolder url="file://$MODULE_DIR$/src/com/awspaas/user/apps/donenow_tst" isTestSource="false" packagePrefix="com.awspaas.user.apps.donenow_ivt" />
+    </content>
+    <orderEntry type="jdk" jdkName="temurin-11" jdkType="JavaSDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="aws_lib" level="project" />
+  </component>
+</module>

BIN
com.awspaas.user.apps.donenow_tst/lib/com.awspaas.user.apps.donenow_tst.jar


+ 104 - 0
com.awspaas.user.apps.donenow_tst/src/com/awspaas/user/apps/donenow_tst/controller/testController.java

@@ -0,0 +1,104 @@
+package com.awspaas.user.apps.donenow_ivt.controller;
+
+import com.actionsoft.bpms.commons.mvc.view.ResponseObject;
+import com.actionsoft.bpms.server.bind.annotation.Controller;
+import com.actionsoft.bpms.server.bind.annotation.Mapping;
+import com.actionsoft.bpms.server.UserContext;
+import com.actionsoft.bpms.commons.database.RowMap;
+import com.actionsoft.bpms.util.DBSql;
+import com.actionsoft.sdk.local.SDK;
+import com.actionsoft.bpms.bo.engine.BO;
+import org.apache.commons.lang3.StringUtils;
+import java.util.HashMap;
+import java.util.Map;
+
+@Controller
+public class testController {
+
+    @Mapping(value = "com.awspaas.user.apps.donenow_tst_updatex")
+    public ResponseObject updateResolution(UserContext uc, String id, String newSolution) {
+        // 参数校验
+        if (StringUtils.isBlank(id)) {
+            return ResponseObject.newErrResponse("ID不能为空");
+        }
+        if (StringUtils.isBlank(newSolution)) {
+            return ResponseObject.newErrResponse("newSolution不能为空");
+        }
+
+        try {
+            // 1. 查询当前解决方案(仅获取需要的字段)
+            String querySql = "select RESOLUTION from BO_EU_DNSDK_TASK where ID = ?";
+            RowMap rowMap = DBSql.getMap(querySql, new Object[]{id});
+
+            // 2. 检查记录是否存在
+            if (rowMap == null) {
+                return ResponseObject.newErrResponse("未找到ID为【" + id + "】的记录");
+            }
+
+            // 3. 拼接新旧内容
+            String currentResolution = rowMap.getString("RESOLUTION");
+            String updatedResolution = StringUtils.isNotBlank(currentResolution)
+                    ? currentResolution + " " + newSolution
+                    : newSolution;
+
+            // 4. 使用BOAPI更新(仅修改RESOLUTION字段,其他字段不变)
+            BO bo = SDK.getBOAPI().get("BO_EU_DNSDK_TASK", id); // 获取BO对象
+            bo.set("RESOLUTION", updatedResolution); // 仅更新需要修改的字段
+            int updateCount = SDK.getBOAPI().update("BO_EU_DNSDK_TASK", bo); // 执行更新
+
+            // 5. 处理更新结果
+            if (updateCount <= 0) {
+                return ResponseObject.newErrResponse("ID为【" + id + "】的记录更新失败(无变更或异常)");
+            }
+
+            // 6. 封装返回数据
+            Map<String, Object> result = new HashMap<>();
+            result.put("updatedResolution", updatedResolution);
+            result.put("id", id);
+
+            // 7. 返回成功响应
+            ResponseObject responseObject = ResponseObject.newOkResponse();
+            responseObject.setData(result);
+            return responseObject;
+
+        } catch (Exception e) {
+            // 捕获并返回异常信息
+            return ResponseObject.newErrResponse("更新失败:" + e.getMessage());
+        }
+    }
+
+    // 状态更新方法(建议也统一使用BOAPI风格)
+    @Mapping(value = "com.awspaas.user.apps.donenow_tst_updatestatus")
+    public ResponseObject updateStatus(UserContext uc, String id, String status) {
+        if (StringUtils.isBlank(id)) {
+            return ResponseObject.newErrResponse("工单ID不能为空");
+        }
+        if (StringUtils.isBlank(status)) {
+            return ResponseObject.newErrResponse("状态值不能为空");
+        }
+
+        try {
+            // 使用BOAPI更新状态(仅修改STATUS_ID字段)
+            BO bo = SDK.getBOAPI().get("BO_EU_DNSDK_TASK", id);
+            if (bo == null) {
+                return ResponseObject.newErrResponse("未找到ID为【" + id + "】的记录");
+            }
+            bo.set("STATUS_ID", status); // 仅更新状态字段
+            int updateCount = SDK.getBOAPI().update("BO_EU_DNSDK_TASK", bo);
+
+            if (updateCount <= 0) {
+                return ResponseObject.newErrResponse("ID为【" + id + "】的状态更新失败");
+            }
+
+            Map<String, Object> result = new HashMap<>();
+            result.put("id", id);
+            result.put("updatedStatus", status);
+
+            ResponseObject responseObject = ResponseObject.newOkResponse();
+            responseObject.setData(result);
+            return responseObject;
+        } catch (Exception e) {
+            return ResponseObject.newErrResponse("状态更新失败:" + e.getMessage());
+        }
+    }
+}