Commit db7ac74a3a8da570cc85d14c7381f54ae7223fe0

Authored by 房远帅
2 parents 63fa8053 169964c0

Merge branch 'master_after0506' into mater_procurement

# Conflicts:
#	xingyun-api/src/main/resources/db/chujiang/base.sql
Showing 27 changed files with 2106 additions and 2 deletions
@@ -761,8 +761,10 @@ create table if not exists `tbl_contract_distributor_standard` @@ -761,8 +761,10 @@ create table if not exists `tbl_contract_distributor_standard`
761 `standard_approver_id` varchar(32) COMMENT '标准合同审批人ID', 761 `standard_approver_id` varchar(32) COMMENT '标准合同审批人ID',
762 `standard_time` datetime COMMENT '标准合同审批完成时间', 762 `standard_time` datetime COMMENT '标准合同审批完成时间',
763 `price_spec_locked` TINYINT(1) COMMENT '是否已完成锁价/锁规', 763 `price_spec_locked` TINYINT(1) COMMENT '是否已完成锁价/锁规',
  764 + `price_lock_user_id` varchar(32) COMMENT '锁价人员ID',
764 `signed_contract_file_id` VARCHAR(100) COMMENT '双方盖章合同ID', 765 `signed_contract_file_id` VARCHAR(100) COMMENT '双方盖章合同ID',
765 `signed_contract_file_name` VARCHAR(255) COMMENT '双方盖章合同名称', 766 `signed_contract_file_name` VARCHAR(255) COMMENT '双方盖章合同名称',
  767 + `changed` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否变更',
766 `formalized_at` datetime comment '转为正式合同时间', 768 `formalized_at` datetime comment '转为正式合同时间',
767 `standardized_at` datetime comment '转为标准合同时间', 769 `standardized_at` datetime comment '转为标准合同时间',
768 `title` varchar(20) comment '合同名称(销售合同、销售订单)', 770 `title` varchar(20) comment '合同名称(销售合同、销售订单)',
@@ -1466,6 +1468,36 @@ ALTER TABLE tbl_purchase_order_line ADD COLUMN production_process text COMMENT ' @@ -1466,6 +1468,36 @@ ALTER TABLE tbl_purchase_order_line ADD COLUMN production_process text COMMENT '
1466 ALTER TABLE tbl_contract_distributor_standard 1468 ALTER TABLE tbl_contract_distributor_standard
1467 ADD COLUMN change_reason varchar(50) DEFAULT NULL COMMENT '变更原因'; 1469 ADD COLUMN change_reason varchar(50) DEFAULT NULL COMMENT '变更原因';
1468 1470
  1471 +ALTER TABLE tbl_contract_distributor_standard
  1472 + ADD COLUMN changed tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否变更';
  1473 +
  1474 +ALTER TABLE tbl_contract_distributor_standard
  1475 + ADD COLUMN price_lock_user_id varchar(32) DEFAULT NULL COMMENT '锁价人员ID';
  1476 +
  1477 +CREATE TABLE IF NOT EXISTS `tbl_contract_change_application`
  1478 +(
  1479 + `id` varchar(32) NOT NULL COMMENT 'ID',
  1480 + `contract_id` varchar(32) NOT NULL COMMENT '合同ID',
  1481 + `root_contract_id` varchar(32) NOT NULL COMMENT '根合同ID',
  1482 + `contract_code` varchar(50) NOT NULL COMMENT '合同编号',
  1483 + `contract_type` varchar(50) NOT NULL COMMENT '合同类型',
  1484 + `contract_stage` varchar(20) NOT NULL COMMENT '合同阶段(FORMAL:正式合同,STANDARD:标准合同)',
  1485 + `change_reason` varchar(500) DEFAULT NULL COMMENT '变更原因',
  1486 + `before_data_json` longtext DEFAULT NULL COMMENT '变更前数据JSON',
  1487 + `after_data_json` longtext DEFAULT NULL COMMENT '变更后数据JSON',
  1488 + `approval_status` varchar(20) NOT NULL COMMENT '审核状态',
  1489 + `create_by_id` varchar(32) DEFAULT NULL COMMENT '创建人ID',
  1490 + `create_by` varchar(50) DEFAULT NULL COMMENT '创建人',
  1491 + `update_by_id` varchar(32) DEFAULT NULL COMMENT '更新人ID',
  1492 + `update_by` varchar(50) DEFAULT NULL COMMENT '更新人',
  1493 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  1494 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  1495 + PRIMARY KEY (`id`),
  1496 + KEY `idx_contract_change_application_contract_id` (`contract_id`),
  1497 + KEY `idx_contract_change_application_root_contract_id` (`root_contract_id`),
  1498 + KEY `idx_contract_change_application_approval_status` (`approval_status`)
  1499 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='合同变更申请单';
  1500 +
1469 ------- 采购------- 1501 ------- 采购-------
1470 1502
1471 CREATE TABLE `procurement_domestic_customer_credit` 1503 CREATE TABLE `procurement_domestic_customer_credit`
  1 +package com.lframework.xingyun.sc.bo.contract;
  2 +
  3 +import com.lframework.starter.web.core.bo.BaseBo;
  4 +import com.lframework.xingyun.sc.entity.ContractChangeApplication;
  5 +import io.swagger.annotations.ApiModelProperty;
  6 +import lombok.Data;
  7 +
  8 +import java.time.LocalDateTime;
  9 +
  10 +/**
  11 + * <p>
  12 + * 合同变更申请单 GetBo
  13 + * </p>
  14 + */
  15 +@Data
  16 +public class GetContractChangeApplicationBo extends BaseBo<ContractChangeApplication> {
  17 +
  18 + /**
  19 + * ID
  20 + */
  21 + @ApiModelProperty("ID")
  22 + private String id;
  23 +
  24 + /**
  25 + * 合同ID
  26 + */
  27 + @ApiModelProperty("合同ID")
  28 + private String contractId;
  29 +
  30 + /**
  31 + * 根合同ID
  32 + */
  33 + @ApiModelProperty("根合同ID")
  34 + private String rootContractId;
  35 +
  36 + /**
  37 + * 合同编号
  38 + */
  39 + @ApiModelProperty("合同编号")
  40 + private String contractCode;
  41 +
  42 + /**
  43 + * 合同类型
  44 + */
  45 + @ApiModelProperty("合同类型")
  46 + private String contractType;
  47 +
  48 + /**
  49 + * 合同阶段
  50 + */
  51 + @ApiModelProperty("合同阶段")
  52 + private String contractStage;
  53 +
  54 + /**
  55 + * 变更原因
  56 + */
  57 + @ApiModelProperty("变更原因")
  58 + private String changeReason;
  59 +
  60 + /**
  61 + * 审核状态
  62 + */
  63 + @ApiModelProperty("审核状态")
  64 + private String approvalStatus;
  65 +
  66 + /**
  67 + * 审核人ID
  68 + */
  69 + @ApiModelProperty("审核人ID")
  70 + private String approverId;
  71 +
  72 + /**
  73 + * 审核时间
  74 + */
  75 + @ApiModelProperty("审核时间")
  76 + private LocalDateTime approvedAt;
  77 +
  78 + /**
  79 + * 是否展示审核按钮
  80 + */
  81 + @ApiModelProperty("是否展示审核按钮")
  82 + private Boolean showExamine;
  83 +
  84 + /**
  85 + * 变更后的合同数据
  86 + */
  87 + @ApiModelProperty("变更后的合同数据")
  88 + private GetContractDistributorStandardBo contractData;
  89 +
  90 + public GetContractChangeApplicationBo() {
  91 + }
  92 +
  93 + public GetContractChangeApplicationBo(ContractChangeApplication dto) {
  94 + super(dto);
  95 + }
  96 +}
@@ -81,6 +81,12 @@ public class GetContractDistributorLineBo extends BaseBo<ContractDistributorLine @@ -81,6 +81,12 @@ public class GetContractDistributorLineBo extends BaseBo<ContractDistributorLine
81 private BigDecimal quantity; 81 private BigDecimal quantity;
82 82
83 /** 83 /**
  84 + * 剩余锁规数量
  85 + */
  86 + @ApiModelProperty("剩余锁规数量")
  87 + private BigDecimal remainingQuantity;
  88 +
  89 + /**
84 * 加工费 90 * 加工费
85 */ 91 */
86 @ApiModelProperty(value = "加工费") 92 @ApiModelProperty(value = "加工费")
@@ -437,9 +437,27 @@ public class GetContractDistributorStandardBo extends BaseBo<ContractDistributor @@ -437,9 +437,27 @@ public class GetContractDistributorStandardBo extends BaseBo<ContractDistributor
437 @ApiModelProperty(value = "是否已完成锁价/锁规") 437 @ApiModelProperty(value = "是否已完成锁价/锁规")
438 private Boolean priceSpecLocked; 438 private Boolean priceSpecLocked;
439 439
  440 + /**
  441 + * 锁价人员ID
  442 + */
  443 + @ApiModelProperty(value = "锁价人员ID")
  444 + private String priceLockUserId;
  445 +
  446 + /**
  447 + * 锁价人员名称
  448 + */
  449 + @ApiModelProperty(value = "锁价人员名称")
  450 + private String priceLockUserName;
  451 +
440 @ApiModelProperty(value = "变更原因") 452 @ApiModelProperty(value = "变更原因")
441 private String changeReason; 453 private String changeReason;
442 454
  455 + /**
  456 + * 是否变更
  457 + */
  458 + @ApiModelProperty(value = "是否变更")
  459 + private Boolean changed;
  460 +
443 @ApiModelProperty(value = "剩余数量") 461 @ApiModelProperty(value = "剩余数量")
444 private BigDecimal remainingQuantity; 462 private BigDecimal remainingQuantity;
445 463
@@ -479,6 +497,13 @@ public class GetContractDistributorStandardBo extends BaseBo<ContractDistributor @@ -479,6 +497,13 @@ public class GetContractDistributorStandardBo extends BaseBo<ContractDistributor
479 @ApiModelProperty(value = "是否可拆分") 497 @ApiModelProperty(value = "是否可拆分")
480 private Boolean canSplit; 498 private Boolean canSplit;
481 499
  500 +
  501 + /**
  502 + * 是否可锁价
  503 + */
  504 + @ApiModelProperty(value = "是否可锁价")
  505 + private Boolean canPriceLock;
  506 +
482 /** 507 /**
483 * 创建人 508 * 创建人
484 */ 509 */
  1 +package com.lframework.xingyun.sc.bo.contract;
  2 +
  3 +import com.lframework.starter.web.core.bo.BaseBo;
  4 +import com.lframework.xingyun.sc.entity.ContractChangeApplication;
  5 +import io.swagger.annotations.ApiModelProperty;
  6 +import lombok.Data;
  7 +
  8 +import java.math.BigDecimal;
  9 +import java.time.LocalDateTime;
  10 +
  11 +/**
  12 + * <p>
  13 + * 合同变更申请单 QueryBo
  14 + * </p>
  15 + */
  16 +@Data
  17 +public class QueryContractChangeApplicationBo extends BaseBo<ContractChangeApplication> {
  18 +
  19 + /**
  20 + * ID
  21 + */
  22 + @ApiModelProperty("ID")
  23 + private String id;
  24 +
  25 + /**
  26 + * 合同ID
  27 + */
  28 + @ApiModelProperty("合同ID")
  29 + private String contractId;
  30 +
  31 + /**
  32 + * 根合同ID
  33 + */
  34 + @ApiModelProperty("根合同ID")
  35 + private String rootContractId;
  36 +
  37 + /**
  38 + * 合同编号
  39 + */
  40 + @ApiModelProperty("合同编号")
  41 + private String contractCode;
  42 +
  43 + /**
  44 + * 合同类型
  45 + */
  46 + @ApiModelProperty("合同类型")
  47 + private String contractType;
  48 +
  49 + /**
  50 + * 合同阶段
  51 + */
  52 + @ApiModelProperty("合同阶段")
  53 + private String contractStage;
  54 +
  55 + /**
  56 + * 变更原因
  57 + */
  58 + @ApiModelProperty("变更原因")
  59 + private String changeReason;
  60 +
  61 + /**
  62 + * 审核状态
  63 + */
  64 + @ApiModelProperty("审核状态")
  65 + private String approvalStatus;
  66 +
  67 + /**
  68 + * 是否展示审核按钮
  69 + */
  70 + @ApiModelProperty("是否展示审核按钮")
  71 + private Boolean showExamine;
  72 +
  73 + /**
  74 + * 创建人
  75 + */
  76 + @ApiModelProperty("创建人")
  77 + private String createBy;
  78 +
  79 + /**
  80 + * 办事处编码
  81 + */
  82 + @ApiModelProperty("办事处编码")
  83 + private String deptCode;
  84 +
  85 + /**
  86 + * 办事处名称
  87 + */
  88 + @ApiModelProperty("办事处名称")
  89 + private String deptCodeName;
  90 +
  91 + /**
  92 + * 生产厂编码
  93 + */
  94 + @ApiModelProperty("生产厂编码")
  95 + private String workshopCode;
  96 +
  97 + /**
  98 + * 生产厂名称
  99 + */
  100 + @ApiModelProperty("生产厂名称")
  101 + private String workshopName;
  102 +
  103 + /**
  104 + * 变更后的需方名称
  105 + */
  106 + @ApiModelProperty("变更后的需方名称")
  107 + private String buyerName;
  108 +
  109 + /**
  110 + * 变更后的合计金额
  111 + */
  112 + @ApiModelProperty("变更后的合计金额")
  113 + private BigDecimal totalAmountIncludingTax;
  114 +
  115 + /**
  116 + * 变更后的合计数量
  117 + */
  118 + @ApiModelProperty("变更后的合计数量")
  119 + private BigDecimal totalQuantity;
  120 +
  121 + /**
  122 + * 创建时间
  123 + */
  124 + @ApiModelProperty("创建时间")
  125 + private LocalDateTime createTime;
  126 +
  127 + public QueryContractChangeApplicationBo() {
  128 + }
  129 +
  130 + public QueryContractChangeApplicationBo(ContractChangeApplication dto) {
  131 + super(dto);
  132 + }
  133 +}
@@ -153,6 +153,18 @@ public class QueryContractDistributorStandardBo extends BaseBo<ContractDistribut @@ -153,6 +153,18 @@ public class QueryContractDistributorStandardBo extends BaseBo<ContractDistribut
153 private BigDecimal totalAmountIncludingTax; 153 private BigDecimal totalAmountIncludingTax;
154 154
155 /** 155 /**
  156 + * 生产厂ID
  157 + */
  158 + @ApiModelProperty("生产厂ID")
  159 + private String workshopId;
  160 +
  161 + /**
  162 + * 生产厂名称
  163 + */
  164 + @ApiModelProperty("生产厂名称")
  165 + private String workshopName;
  166 +
  167 + /**
156 * 合计数量 168 * 合计数量
157 */ 169 */
158 @ApiModelProperty("合计数量") 170 @ApiModelProperty("合计数量")
@@ -216,9 +228,27 @@ public class QueryContractDistributorStandardBo extends BaseBo<ContractDistribut @@ -216,9 +228,27 @@ public class QueryContractDistributorStandardBo extends BaseBo<ContractDistribut
216 @ApiModelProperty(value = "是否已完成锁价/锁规") 228 @ApiModelProperty(value = "是否已完成锁价/锁规")
217 private Boolean priceSpecLocked; 229 private Boolean priceSpecLocked;
218 230
  231 + /**
  232 + * 锁价人员ID
  233 + */
  234 + @ApiModelProperty(value = "锁价人员ID")
  235 + private String priceLockUserId;
  236 +
  237 + /**
  238 + * 锁价人员名称
  239 + */
  240 + @ApiModelProperty(value = "锁价人员名称")
  241 + private String priceLockUserName;
  242 +
219 @ApiModelProperty(value = "变更原因") 243 @ApiModelProperty(value = "变更原因")
220 private String changeReason; 244 private String changeReason;
221 245
  246 + /**
  247 + * 是否变更
  248 + */
  249 + @ApiModelProperty(value = "是否变更")
  250 + private Boolean changed;
  251 +
222 @ApiModelProperty(value = "剩余数量") 252 @ApiModelProperty(value = "剩余数量")
223 private BigDecimal remainingQuantity; 253 private BigDecimal remainingQuantity;
224 254
@@ -240,6 +270,12 @@ public class QueryContractDistributorStandardBo extends BaseBo<ContractDistribut @@ -240,6 +270,12 @@ public class QueryContractDistributorStandardBo extends BaseBo<ContractDistribut
240 @ApiModelProperty(value = "是否可拆分") 270 @ApiModelProperty(value = "是否可拆分")
241 private Boolean canSplit; 271 private Boolean canSplit;
242 272
  273 + /**
  274 + * 是否可锁价
  275 + */
  276 + @ApiModelProperty(value = "是否可锁价")
  277 + private Boolean canPriceLock;
  278 +
243 279
244 public QueryContractDistributorStandardBo() { 280 public QueryContractDistributorStandardBo() {
245 281
1 package com.lframework.xingyun.sc.bo.order; 1 package com.lframework.xingyun.sc.bo.order;
2 2
  3 +import com.baomidou.mybatisplus.annotation.FieldFill;
3 import com.baomidou.mybatisplus.annotation.TableField; 4 import com.baomidou.mybatisplus.annotation.TableField;
4 import com.fasterxml.jackson.annotation.JsonFormat; 5 import com.fasterxml.jackson.annotation.JsonFormat;
5 import com.lframework.starter.common.constants.StringPool; 6 import com.lframework.starter.common.constants.StringPool;
@@ -7,6 +8,7 @@ import com.lframework.starter.web.core.bo.BaseBo; @@ -7,6 +8,7 @@ import com.lframework.starter.web.core.bo.BaseBo;
7 8
8 import java.math.BigDecimal; 9 import java.math.BigDecimal;
9 import java.time.LocalDate; 10 import java.time.LocalDate;
  11 +import java.time.LocalDateTime;
10 import java.util.List; 12 import java.util.List;
11 13
12 import com.lframework.xingyun.sc.entity.PurchaseOrderInfo; 14 import com.lframework.xingyun.sc.entity.PurchaseOrderInfo;
@@ -350,6 +352,12 @@ public class GetPurchaseOrderInfoBo extends BaseBo<PurchaseOrderInfo> { @@ -350,6 +352,12 @@ public class GetPurchaseOrderInfoBo extends BaseBo<PurchaseOrderInfo> {
350 @ApiModelProperty("是否展示上传按钮") 352 @ApiModelProperty("是否展示上传按钮")
351 private boolean showUpload = false; 353 private boolean showUpload = false;
352 354
  355 + /**
  356 + * 创建时间
  357 + */
  358 + @ApiModelProperty("创建时间")
  359 + private LocalDateTime createTime;
  360 +
353 361
354 public GetPurchaseOrderInfoBo() { 362 public GetPurchaseOrderInfoBo() {
355 363
@@ -266,6 +266,11 @@ public class OrderChangeRecordBo extends BaseBo<OrderInfoChangeRecord> { @@ -266,6 +266,11 @@ public class OrderChangeRecordBo extends BaseBo<OrderInfoChangeRecord> {
266 @ApiModelProperty("合同类型") 266 @ApiModelProperty("合同类型")
267 private String contractType; 267 private String contractType;
268 268
  269 + /**
  270 + * 订货单状态
  271 + */
  272 + @ApiModelProperty("订货单状态")
  273 + private String status;
269 274
270 public OrderChangeRecordBo() { 275 public OrderChangeRecordBo() {
271 276
  1 +package com.lframework.xingyun.sc.controller.contract;
  2 +
  3 +import com.lframework.starter.common.exceptions.impl.DefaultClientException;
  4 +import com.lframework.starter.web.core.annotations.security.HasPermission;
  5 +import com.lframework.starter.web.core.components.resp.InvokeResult;
  6 +import com.lframework.starter.web.core.components.resp.InvokeResultBuilder;
  7 +import com.lframework.starter.web.core.components.resp.PageResult;
  8 +import com.lframework.starter.web.core.controller.DefaultBaseController;
  9 +import com.lframework.starter.web.core.utils.JsonUtil;
  10 +import com.lframework.starter.web.core.utils.PageResultUtil;
  11 +import com.lframework.starter.web.inner.dto.dic.city.DicCityDto;
  12 +import com.lframework.starter.web.inner.entity.SysDataDicItem;
  13 +import com.lframework.starter.web.inner.service.DicCityService;
  14 +import com.lframework.starter.web.inner.service.system.SysDataDicItemService;
  15 +import com.lframework.starter.web.inner.entity.SysDept;
  16 +import com.lframework.starter.web.inner.service.system.SysDeptService;
  17 +import com.lframework.xingyun.basedata.entity.Customer;
  18 +import com.lframework.xingyun.basedata.entity.Workshop;
  19 +import com.lframework.xingyun.basedata.service.customer.CustomerService;
  20 +import com.lframework.xingyun.basedata.service.workshop.WorkshopService;
  21 +import com.lframework.xingyun.sc.bo.contract.GetContractChangeApplicationBo;
  22 +import com.lframework.xingyun.sc.bo.contract.GetContractDistributorStandardBo;
  23 +import com.lframework.xingyun.sc.bo.contract.QueryContractChangeApplicationBo;
  24 +import com.lframework.xingyun.sc.bo.contract.QueryContractDistributorStandardBo;
  25 +import com.lframework.xingyun.sc.entity.ContractChangeApplication;
  26 +import com.lframework.xingyun.sc.entity.ContractDistributorStandard;
  27 +import com.lframework.xingyun.sc.service.contract.ContractChangeApplicationService;
  28 +import com.lframework.xingyun.sc.vo.contract.createVo.CreateContractChangeApplicationVo;
  29 +import com.lframework.xingyun.sc.vo.contract.queryVo.QueryContractChangeApplicationVo;
  30 +import com.lframework.xingyun.sc.vo.contract.queryVo.QueryContractChangeSelectableContractVo;
  31 +import com.lframework.xingyun.sc.vo.contract.updateVo.UpdateContractChangeApplicationVo;
  32 +import io.swagger.annotations.Api;
  33 +import io.swagger.annotations.ApiImplicitParam;
  34 +import io.swagger.annotations.ApiOperation;
  35 +import org.apache.commons.collections4.CollectionUtils;
  36 +import org.apache.commons.lang3.StringUtils;
  37 +import org.springframework.beans.factory.annotation.Autowired;
  38 +import org.springframework.validation.annotation.Validated;
  39 +import org.springframework.web.bind.annotation.*;
  40 +import javax.validation.Valid;
  41 +import javax.validation.constraints.NotBlank;
  42 +import java.util.Map;
  43 +import java.util.function.Function;
  44 +import java.util.List;
  45 +import java.util.stream.Collectors;
  46 +
  47 +/**
  48 + * 合同变更申请单 Controller
  49 + */
  50 +@Api(tags = "合同变更申请单")
  51 +@Validated
  52 +@RestController
  53 +@RequestMapping("/contract/contractChangeApplication")
  54 +public class ContractChangeApplicationController extends DefaultBaseController {
  55 +
  56 + @Autowired
  57 + private ContractChangeApplicationService contractChangeApplicationService;
  58 + @Autowired
  59 + private CustomerService customerService;
  60 + @Autowired
  61 + private SysDeptService sysDeptService;
  62 + @Autowired
  63 + private WorkshopService workshopService;
  64 + @Autowired
  65 + private SysDataDicItemService sysDataDicItemService;
  66 + @Autowired
  67 + private DicCityService dicCityService;
  68 +
  69 + /**
  70 + * 查询列表
  71 + */
  72 + @ApiOperation("查询列表")
  73 + @HasPermission({"contract-manage:change-contract:query"})
  74 + @GetMapping("/query")
  75 + public InvokeResult<PageResult<QueryContractChangeApplicationBo>> query(QueryContractChangeApplicationVo vo) {
  76 + PageResult<ContractChangeApplication> pageResult = contractChangeApplicationService.query(getPageIndex(vo), getPageSize(vo), vo);
  77 + List<QueryContractChangeApplicationBo> results = null;
  78 + if (CollectionUtils.isNotEmpty(pageResult.getDatas())) {
  79 + results = pageResult.getDatas().stream().map(QueryContractChangeApplicationBo::new).collect(Collectors.toList());
  80 + }
  81 + return InvokeResultBuilder.success(PageResultUtil.rebuild(pageResult, results));
  82 + }
  83 +
  84 + /**
  85 + * 根据ID查询
  86 + */
  87 + @ApiOperation("根据ID查询")
  88 + @ApiImplicitParam(value = "id", name = "id", paramType = "query", required = true)
  89 + @HasPermission({"contract-manage:change-contract:query","contract-manage:change-contract:review"})
  90 + @GetMapping
  91 + public InvokeResult<GetContractChangeApplicationBo> get(@NotBlank(message = "id不能为空!") String id) {
  92 + ContractChangeApplication data = contractChangeApplicationService.findById(id);
  93 + if (data == null) {
  94 + throw new DefaultClientException("合同变更申请单不存在!");
  95 + }
  96 +
  97 + GetContractChangeApplicationBo result = new GetContractChangeApplicationBo(data);
  98 + if (StringUtils.isNotBlank(data.getAfterDataJson())) {
  99 + GetContractDistributorStandardBo contractData = JsonUtil.parseObject(data.getAfterDataJson(), GetContractDistributorStandardBo.class);
  100 + fillContractDataDisplayInfo(contractData);
  101 + result.setContractData(contractData);
  102 + }
  103 + return InvokeResultBuilder.success(result);
  104 + }
  105 +
  106 + /**
  107 + * 查询可发起变更的合同
  108 + */
  109 + @ApiOperation("查询可发起变更的合同")
  110 + @HasPermission({
  111 + "contract-manage:distribution-standard-contract:query",
  112 + "contract-manage:distribution-inventory-contract:query",
  113 + "contract-manage:distribution-unlocked-contract:query",
  114 + "contract-manage:foreign-trade-standard-contract:query",
  115 + "contract-manage:foreign-trade-inventory-contract:query",
  116 + "contract-manage:foreign-trade-unlocked-contract:query",
  117 + "contract-manage:processed-standard-contract:query"
  118 + })
  119 + @GetMapping("/querySelectableContracts")
  120 + public InvokeResult<PageResult<QueryContractDistributorStandardBo>> querySelectableContracts(QueryContractChangeSelectableContractVo vo) {
  121 + PageResult<ContractDistributorStandard> pageResult = contractChangeApplicationService
  122 + .querySelectableContracts(getPageIndex(vo), getPageSize(vo), vo);
  123 + List<QueryContractDistributorStandardBo> results = null;
  124 + if (CollectionUtils.isNotEmpty(pageResult.getDatas())) {
  125 + results = pageResult.getDatas().stream().map(QueryContractDistributorStandardBo::new).collect(Collectors.toList());
  126 + Map<String, Customer> customerMap = customerService.listByIds(results.stream()
  127 + .map(QueryContractDistributorStandardBo::getBuyer)
  128 + .collect(Collectors.toSet()))
  129 + .stream()
  130 + .collect(Collectors.toMap(Customer::getId, Function.identity()));
  131 + Map<String, SysDept> deptMap = sysDeptService.listByIds(results.stream()
  132 + .map(QueryContractDistributorStandardBo::getDeptId)
  133 + .collect(Collectors.toSet()))
  134 + .stream()
  135 + .collect(Collectors.toMap(SysDept::getId, Function.identity()));
  136 + Map<String, Workshop> workshopMap = workshopService.listByIds(results.stream()
  137 + .map(QueryContractDistributorStandardBo::getWorkshopId)
  138 + .collect(Collectors.toSet()))
  139 + .stream()
  140 + .collect(Collectors.toMap(Workshop::getId, Function.identity()));
  141 + results.forEach(item -> {
  142 + Customer customer = customerMap.get(item.getBuyer());
  143 + if (customer != null) {
  144 + item.setBuyerName(customer.getName());
  145 + }
  146 + SysDept dept = deptMap.get(item.getDeptId());
  147 + if (dept != null) {
  148 + item.setDeptName(dept.getName());
  149 + }
  150 + Workshop workshop = workshopMap.get(item.getWorkshopId());
  151 + if (workshop != null) {
  152 + item.setWorkshopName(workshop.getName());
  153 + }
  154 + });
  155 + }
  156 + return InvokeResultBuilder.success(PageResultUtil.rebuild(pageResult, results));
  157 + }
  158 +
  159 + /**
  160 + * 新增
  161 + */
  162 + @ApiOperation("新增")
  163 + @HasPermission({"contract-manage:change-contract:add"})
  164 + @PostMapping
  165 + public InvokeResult<Void> create(@Valid @RequestBody CreateContractChangeApplicationVo vo) throws Exception {
  166 + contractChangeApplicationService.create(vo);
  167 + return InvokeResultBuilder.success();
  168 + }
  169 +
  170 + /**
  171 + * 修改
  172 + */
  173 + @ApiOperation("修改")
  174 + @HasPermission({"contract-manage:change-contract:modify","contract-manage:change-contract:approve"})
  175 + @PutMapping
  176 + public InvokeResult<Void> update(@Valid @RequestBody UpdateContractChangeApplicationVo vo) throws Exception {
  177 + contractChangeApplicationService.update(vo);
  178 + return InvokeResultBuilder.success();
  179 + }
  180 +
  181 + /**
  182 + * 取消
  183 + */
  184 + @ApiOperation("取消")
  185 + @ApiImplicitParam(value = "id", name = "id", paramType = "query", required = true)
  186 + @HasPermission({"contract-manage:change-contract:cancel"})
  187 + @PostMapping("/cancel")
  188 + public InvokeResult<Void> cancel(@NotBlank(message = "id不能为空!") String id) {
  189 + contractChangeApplicationService.cancelApplication(id);
  190 + return InvokeResultBuilder.success();
  191 + }
  192 +
  193 + /**
  194 + * 填充变更后合同数据的展示字段
  195 + *
  196 + * @param contractData 合同数据
  197 + */
  198 + private void fillContractDataDisplayInfo(GetContractDistributorStandardBo contractData) {
  199 + if (contractData == null) {
  200 + return;
  201 + }
  202 +
  203 + if (StringUtils.isNotBlank(contractData.getBuyer())) {
  204 + Customer customer = customerService.findById(contractData.getBuyer());
  205 + contractData.setBuyerName(customer == null ? null : customer.getName());
  206 + }
  207 + if (StringUtils.isNotBlank(contractData.getStockUpCompanyId())) {
  208 + Customer customer = customerService.findById(contractData.getStockUpCompanyId());
  209 + contractData.setStockUpCompanyName(customer == null ? null : customer.getName());
  210 + }
  211 + if (StringUtils.isNotBlank(contractData.getDeptId())) {
  212 + SysDept dept = sysDeptService.findById(contractData.getDeptId());
  213 + contractData.setDeptName(dept == null ? null : dept.getName());
  214 + }
  215 + if (StringUtils.isNotBlank(contractData.getRegion())) {
  216 + SysDept dept = sysDeptService.findById(contractData.getRegion());
  217 + contractData.setRegionName(dept == null ? null : dept.getName());
  218 + }
  219 + if (StringUtils.isNotBlank(contractData.getWorkshopId())) {
  220 + Workshop workshop = workshopService.findById(contractData.getWorkshopId());
  221 + contractData.setWorkshopName(workshop == null ? null : workshop.getName());
  222 + }
  223 +
  224 + SysDataDicItem supplierDicItem = sysDataDicItemService.findByCode(ContractDistributorStandardController.SUPPLIER_DIC_CODE,
  225 + contractData.getSupplier());
  226 + contractData.setSupplierName(supplierDicItem == null ? null : supplierDicItem.getName());
  227 + SysDataDicItem unitDicItem = sysDataDicItemService.findByCode(ContractDistributorStandardController.UNIT_DIC_CODE,
  228 + contractData.getUnit());
  229 + contractData.setUnitName(unitDicItem == null ? null : unitDicItem.getName());
  230 + SysDataDicItem requiredDicItem = sysDataDicItemService.findByCode(ContractDistributorStandardController.CONDITIONS_REQUIRED_DIC_CODE,
  231 + contractData.getSpecialTerms());
  232 + contractData.setSpecialTermsName(requiredDicItem == null ? null : requiredDicItem.getName());
  233 + SysDataDicItem standardDicItem = sysDataDicItemService.findByCode(ContractDistributorStandardController.APPLICABLE_STANDARD_DIC_CODE,
  234 + contractData.getExecutionStandard());
  235 + contractData.setExecutionStandardName(standardDicItem == null ? null : standardDicItem.getName());
  236 +
  237 + List<DicCityDto> dicCityDtoList = dicCityService.getChainById(contractData.getDestination());
  238 + if (CollectionUtils.isNotEmpty(dicCityDtoList) && dicCityDtoList.size() == 3) {
  239 + contractData.setProvinceId(dicCityDtoList.get(0).getId());
  240 + contractData.setProvinceName(dicCityDtoList.get(0).getName());
  241 + contractData.setCityId(dicCityDtoList.get(1).getId());
  242 + contractData.setCityName(dicCityDtoList.get(1).getName());
  243 + contractData.setDistrictId(dicCityDtoList.get(2).getId());
  244 + contractData.setDistrictName(dicCityDtoList.get(2).getName());
  245 + }
  246 +
  247 + fillContractLineDisplayInfo(contractData);
  248 + }
  249 +
  250 + /**
  251 + * 填充变更后合同物料行展示字段
  252 + *
  253 + * @param contractData 合同数据
  254 + */
  255 + private void fillContractLineDisplayInfo(GetContractDistributorStandardBo contractData) {
  256 + if (contractData == null) {
  257 + return;
  258 + }
  259 +
  260 + Map<String, String> productCodeAndNameMap = sysDataDicItemService.findByDicCode(ContractDistributorStandardController.CONTRACT_PRODUCT_DIC_CODE)
  261 + .stream()
  262 + .collect(Collectors.toMap(SysDataDicItem::getCode, SysDataDicItem::getName));
  263 +
  264 + if (CollectionUtils.isNotEmpty(contractData.getContractDistributorLineList())) {
  265 + contractData.getContractDistributorLineList().forEach(line -> line.setProductName(productCodeAndNameMap.get(line.getProductId())));
  266 + }
  267 +
  268 + if (CollectionUtils.isNotEmpty(contractData.getContractStdProcessingLineList())) {
  269 + Map<String, String> rawToProdRatioCodeAndNameMap = sysDataDicItemService
  270 + .findByDicCode(ContractDistributorStandardController.RAW_TO_PROD_RATIO_DIC_CODE)
  271 + .stream()
  272 + .collect(Collectors.toMap(SysDataDicItem::getCode, SysDataDicItem::getName));
  273 + Map<String, String> rawMaterialCodeAndNameMap = sysDataDicItemService
  274 + .findByDicCode(ContractDistributorStandardController.RAW_MATERIAL)
  275 + .stream()
  276 + .collect(Collectors.toMap(SysDataDicItem::getCode, SysDataDicItem::getName));
  277 + Map<String, String> rawProductGradeCodeAndNameMap = sysDataDicItemService
  278 + .findByDicCode(ContractDistributorStandardController.RAW_MATERIAL_GRADE)
  279 + .stream()
  280 + .collect(Collectors.toMap(SysDataDicItem::getCode, SysDataDicItem::getName));
  281 +
  282 + contractData.getContractStdProcessingLineList().forEach(line -> {
  283 + line.setRawProductName(rawMaterialCodeAndNameMap.get(line.getRawProductId()));
  284 + line.setRawProductGradeName(rawProductGradeCodeAndNameMap.get(line.getRawProductGrade()));
  285 + line.setMaterialProductRatioName(rawToProdRatioCodeAndNameMap.get(line.getMaterialProductRatio()));
  286 + line.setProductName(productCodeAndNameMap.get(line.getProductId()));
  287 + });
  288 + }
  289 + }
  290 +}
@@ -225,6 +225,19 @@ public class ContractDistributorStandardController extends DefaultBaseController @@ -225,6 +225,19 @@ public class ContractDistributorStandardController extends DefaultBaseController
225 List<SysDept> regionList = sysDeptService.listByIds(regionIds); 225 List<SysDept> regionList = sysDeptService.listByIds(regionIds);
226 regionMap = regionList.stream().collect(Collectors.toMap(SysDept::getId, SysDept::getName)); 226 regionMap = regionList.stream().collect(Collectors.toMap(SysDept::getId, SysDept::getName));
227 } 227 }
  228 + List<String> priceLockUserIds = boList.stream()
  229 + .map(QueryContractDistributorStandardBo::getPriceLockUserId)
  230 + .filter(StringUtils::isNotBlank)
  231 + .distinct()
  232 + .collect(Collectors.toList());
  233 + final Map<String, SysUser> priceLockUserMap;
  234 + if (CollectionUtils.isNotEmpty(priceLockUserIds)) {
  235 + priceLockUserMap = CollectionUtils.emptyIfNull(sysUserService.listByIds(priceLockUserIds))
  236 + .stream()
  237 + .collect(Collectors.toMap(SysUser::getId, Function.identity()));
  238 + } else {
  239 + priceLockUserMap = Collections.emptyMap();
  240 + }
228 Map<String, String> finalRegionMap = regionMap; 241 Map<String, String> finalRegionMap = regionMap;
229 boList.forEach(bo -> { 242 boList.forEach(bo -> {
230 if (bo == null) { 243 if (bo == null) {
@@ -267,6 +280,10 @@ public class ContractDistributorStandardController extends DefaultBaseController @@ -267,6 +280,10 @@ public class ContractDistributorStandardController extends DefaultBaseController
267 Customer customer = customerMap.get(bo.getStockUpCompanyId()); 280 Customer customer = customerMap.get(bo.getStockUpCompanyId());
268 bo.setStockUpCompanyName(customer == null ? "" : customer.getName()); 281 bo.setStockUpCompanyName(customer == null ? "" : customer.getName());
269 } 282 }
  283 + if (StringUtils.isNotBlank(bo.getPriceLockUserId())) {
  284 + SysUser priceLockUser = priceLockUserMap.get(bo.getPriceLockUserId());
  285 + bo.setPriceLockUserName(priceLockUser == null ? "" : priceLockUser.getName());
  286 + }
270 //合同状态(标准合同列表展示) 287 //合同状态(标准合同列表展示)
271 if (vo != null && "STANDARD".equals(vo.getStatus())) { 288 if (vo != null && "STANDARD".equals(vo.getStatus())) {
272 String contractId = bo.getId(); 289 String contractId = bo.getId();
@@ -374,6 +391,7 @@ public class ContractDistributorStandardController extends DefaultBaseController @@ -374,6 +391,7 @@ public class ContractDistributorStandardController extends DefaultBaseController
374 contractDistributorLineBo.setProductName(productName); 391 contractDistributorLineBo.setProductName(productName);
375 lineBoList.add(contractDistributorLineBo); 392 lineBoList.add(contractDistributorLineBo);
376 }); 393 });
  394 + fillUnlockedContractLineRemainingQuantity(result, lineBoList);
377 395
378 result.setContractDistributorLineList(lineBoList); 396 result.setContractDistributorLineList(lineBoList);
379 } 397 }
@@ -413,6 +431,10 @@ public class ContractDistributorStandardController extends DefaultBaseController @@ -413,6 +431,10 @@ public class ContractDistributorStandardController extends DefaultBaseController
413 Customer customer1 = customerService.findById(result.getStockUpCompanyId()); 431 Customer customer1 = customerService.findById(result.getStockUpCompanyId());
414 result.setStockUpCompanyName(customer1 == null ? null : customer1.getName()); 432 result.setStockUpCompanyName(customer1 == null ? null : customer1.getName());
415 } 433 }
  434 + if (StringUtils.isNotBlank(result.getPriceLockUserId())) {
  435 + SysUser priceLockUser = sysUserService.findById(result.getPriceLockUserId());
  436 + result.setPriceLockUserName(priceLockUser == null ? null : priceLockUser.getName());
  437 + }
416 //合同状态(标准合同列表展示) 438 //合同状态(标准合同列表展示)
417 if ("STANDARD".equals(data.getStatus())) { 439 if ("STANDARD".equals(data.getStatus())) {
418 String shippingStatusName = Stream.of( 440 String shippingStatusName = Stream.of(
@@ -447,6 +469,58 @@ public class ContractDistributorStandardController extends DefaultBaseController @@ -447,6 +469,58 @@ public class ContractDistributorStandardController extends DefaultBaseController
447 } 469 }
448 470
449 /** 471 /**
  472 + * 回填未锁规合同子表剩余锁规数量
  473 + *
  474 + * @param contract 合同
  475 + * @param lineBoList 合同子表
  476 + */
  477 + private void fillUnlockedContractLineRemainingQuantity(GetContractDistributorStandardBo contract,
  478 + List<GetContractDistributorLineBo> lineBoList) {
  479 + if (contract == null || CollectionUtils.isEmpty(lineBoList)) {
  480 + return;
  481 + }
  482 + if (!"DRAFT_DIST_AGMT".equals(contract.getType()) && !"INTL_OPEN_SPEC_AGMT".equals(contract.getType())) {
  483 + return;
  484 + }
  485 + if (StringUtils.isBlank(contract.getId())) {
  486 + return;
  487 + }
  488 +
  489 + Wrapper<ContractDistributorStandard> childWrapper = Wrappers.lambdaQuery(ContractDistributorStandard.class)
  490 + .select(ContractDistributorStandard::getId)
  491 + .eq(ContractDistributorStandard::getParentId, contract.getId());
  492 + List<String> childContractIds = CollectionUtils.emptyIfNull(contractDistributorStandardService.list(childWrapper))
  493 + .stream()
  494 + .map(ContractDistributorStandard::getId)
  495 + .filter(StringUtils::isNotBlank)
  496 + .collect(Collectors.toList());
  497 +
  498 + Map<String, BigDecimal> lockedQuantityMap = Collections.emptyMap();
  499 + if (CollectionUtils.isNotEmpty(childContractIds)) {
  500 + Wrapper<ContractDistributorLine> childLineWrapper = Wrappers.lambdaQuery(ContractDistributorLine.class)
  501 + .select(ContractDistributorLine::getItemId, ContractDistributorLine::getQuantity)
  502 + .in(ContractDistributorLine::getContractId, childContractIds);
  503 + lockedQuantityMap = CollectionUtils.emptyIfNull(contractDistributorLineService.list(childLineWrapper))
  504 + .stream()
  505 + .filter(Objects::nonNull)
  506 + .filter(item -> StringUtils.isNotBlank(item.getItemId()))
  507 + .filter(item -> item.getQuantity() != null)
  508 + .collect(Collectors.groupingBy(ContractDistributorLine::getItemId,
  509 + Collectors.reducing(BigDecimal.ZERO, ContractDistributorLine::getQuantity, BigDecimal::add)));
  510 + }
  511 +
  512 + Map<String, BigDecimal> finalLockedQuantityMap = lockedQuantityMap;
  513 + lineBoList.forEach(line -> {
  514 + BigDecimal quantity = line.getQuantity() == null ? BigDecimal.ZERO : line.getQuantity();
  515 + BigDecimal lockedQuantity = StringUtils.isBlank(line.getItemId())
  516 + ? BigDecimal.ZERO
  517 + : finalLockedQuantityMap.getOrDefault(line.getItemId(), BigDecimal.ZERO);
  518 + BigDecimal remainingQuantity = quantity.subtract(lockedQuantity);
  519 + line.setRemainingQuantity(remainingQuantity);
  520 + });
  521 + }
  522 +
  523 + /**
450 * 新增 524 * 新增
451 */ 525 */
452 @ApiOperation("新增") 526 @ApiOperation("新增")
@@ -107,6 +107,7 @@ public class OrderChangeRecordController extends DefaultBaseController { @@ -107,6 +107,7 @@ public class OrderChangeRecordController extends DefaultBaseController {
107 result.setContractType(contractDistributorStandard.getType()); 107 result.setContractType(contractDistributorStandard.getType());
108 } 108 }
109 } 109 }
  110 + result.setStatus(purchaseOrderInfo.getStatus());
110 } 111 }
111 112
112 return InvokeResultBuilder.success(result); 113 return InvokeResultBuilder.success(result);
@@ -442,9 +443,17 @@ public class OrderChangeRecordController extends DefaultBaseController { @@ -442,9 +443,17 @@ public class OrderChangeRecordController extends DefaultBaseController {
442 return true; 443 return true;
443 } 444 }
444 return "UPDATE".equals(line.getType()) && (line.getBrandChange() 445 return "UPDATE".equals(line.getType()) && (line.getBrandChange()
  446 + || line.getIndustryChange()
  447 + || line.getQualityChange()
445 || line.getLengthChange() 448 || line.getLengthChange()
  449 + || line.getLengthTolNegChange()
  450 + || line.getLengthTolPosChange()
446 || line.getWidthChange() 451 || line.getWidthChange()
  452 + || line.getWidthTolNegChange()
  453 + || line.getWidthTolPosChange()
447 || line.getThicknessChange() 454 || line.getThicknessChange()
  455 + || line.getThicknessTolNegChange()
  456 + || line.getThicknessTolPosChange()
448 || line.getStatusChange() 457 || line.getStatusChange()
449 || line.getQuantityChange() 458 || line.getQuantityChange()
450 || line.getSalesPriceChange() 459 || line.getSalesPriceChange()
  1 +package com.lframework.xingyun.sc.entity;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.FieldFill;
  4 +import com.baomidou.mybatisplus.annotation.TableField;
  5 +import com.baomidou.mybatisplus.annotation.TableName;
  6 +import com.lframework.starter.web.core.dto.BaseDto;
  7 +import com.lframework.starter.web.core.entity.BaseEntity;
  8 +import lombok.Data;
  9 +
  10 +import java.math.BigDecimal;
  11 +import java.time.LocalDateTime;
  12 +
  13 +/**
  14 + * <p>
  15 + * 合同变更申请单
  16 + * </p>
  17 + */
  18 +@Data
  19 +@TableName("tbl_contract_change_application")
  20 +public class ContractChangeApplication extends BaseEntity implements BaseDto {
  21 +
  22 + private static final long serialVersionUID = 1L;
  23 +
  24 + public static final String CACHE_NAME = "ContractChangeApplication";
  25 +
  26 + /**
  27 + * ID
  28 + */
  29 + private String id;
  30 +
  31 + /**
  32 + * 合同ID
  33 + */
  34 + private String contractId;
  35 +
  36 + /**
  37 + * 根合同ID
  38 + */
  39 + private String rootContractId;
  40 +
  41 + /**
  42 + * 合同编号
  43 + */
  44 + private String contractCode;
  45 +
  46 + /**
  47 + * 合同类型
  48 + */
  49 + private String contractType;
  50 +
  51 + /**
  52 + * 合同阶段(FORMAL:正式合同,STANDARD:标准合同)
  53 + */
  54 + private String contractStage;
  55 +
  56 + /**
  57 + * 变更原因
  58 + */
  59 + private String changeReason;
  60 +
  61 + /**
  62 + * 变更前数据JSON
  63 + */
  64 + private String beforeDataJson;
  65 +
  66 + /**
  67 + * 变更后数据JSON
  68 + */
  69 + private String afterDataJson;
  70 +
  71 + /**
  72 + * 审核状态
  73 + */
  74 + private String approvalStatus;
  75 +
  76 + /**
  77 + * 办事处编码(非持久化字段)
  78 + */
  79 + @TableField(exist = false)
  80 + private String deptCode;
  81 +
  82 + /**
  83 + * 办事处名称(非持久化字段)
  84 + */
  85 + @TableField(exist = false)
  86 + private String deptCodeName;
  87 +
  88 + /**
  89 + * 生产厂编码(非持久化字段)
  90 + */
  91 + @TableField(exist = false)
  92 + private String workshopCode;
  93 +
  94 + /**
  95 + * 生产厂名称(非持久化字段)
  96 + */
  97 + @TableField(exist = false)
  98 + private String workshopName;
  99 +
  100 + /**
  101 + * 变更后的需方名称(非持久化字段)
  102 + */
  103 + @TableField(exist = false)
  104 + private String buyerName;
  105 +
  106 + /**
  107 + * 变更后的合计金额(非持久化字段)
  108 + */
  109 + @TableField(exist = false)
  110 + private BigDecimal totalAmountIncludingTax;
  111 +
  112 + /**
  113 + * 变更后的合计数量(非持久化字段)
  114 + */
  115 + @TableField(exist = false)
  116 + private BigDecimal totalQuantity;
  117 +
  118 + /**
  119 + * 是否展示审核按钮(非持久化字段)
  120 + */
  121 + @TableField(exist = false)
  122 + private Boolean showExamine;
  123 +
  124 + /**
  125 + * 创建人ID
  126 + */
  127 + @TableField(fill = FieldFill.INSERT)
  128 + private String createById;
  129 +
  130 + /**
  131 + * 创建人
  132 + */
  133 + @TableField(fill = FieldFill.INSERT)
  134 + private String createBy;
  135 +
  136 + /**
  137 + * 更新人ID
  138 + */
  139 + @TableField(fill = FieldFill.INSERT_UPDATE)
  140 + private String updateById;
  141 +
  142 + /**
  143 + * 更新人
  144 + */
  145 + @TableField(fill = FieldFill.INSERT_UPDATE)
  146 + private String updateBy;
  147 +
  148 + /**
  149 + * 创建时间
  150 + */
  151 + @TableField(fill = FieldFill.INSERT)
  152 + private LocalDateTime createTime;
  153 +
  154 + /**
  155 + * 更新时间
  156 + */
  157 + @TableField(fill = FieldFill.INSERT_UPDATE)
  158 + private LocalDateTime updateTime;
  159 +}
@@ -314,11 +314,21 @@ public class ContractDistributorStandard extends BaseEntity implements BaseDto { @@ -314,11 +314,21 @@ public class ContractDistributorStandard extends BaseEntity implements BaseDto {
314 private Boolean priceSpecLocked; 314 private Boolean priceSpecLocked;
315 315
316 /** 316 /**
  317 + * 锁价人员ID
  318 + */
  319 + private String priceLockUserId;
  320 +
  321 + /**
317 * 变更原因 322 * 变更原因
318 */ 323 */
319 private String changeReason; 324 private String changeReason;
320 325
321 /** 326 /**
  327 + * 是否变更
  328 + */
  329 + private Boolean changed;
  330 +
  331 + /**
322 * 双方盖章合同ID 332 * 双方盖章合同ID
323 */ 333 */
324 private String signedContractFileId; 334 private String signedContractFileId;
@@ -369,6 +379,12 @@ public class ContractDistributorStandard extends BaseEntity implements BaseDto { @@ -369,6 +379,12 @@ public class ContractDistributorStandard extends BaseEntity implements BaseDto {
369 private Boolean canSplit; 379 private Boolean canSplit;
370 380
371 /** 381 /**
  382 + * 是否可锁价
  383 + */
  384 + @TableField(exist = false)
  385 + private Boolean canPriceLock;
  386 +
  387 + /**
372 * 剩余锁规数量 388 * 剩余锁规数量
373 */ 389 */
374 @TableField(exist = false) 390 @TableField(exist = false)
@@ -23,6 +23,7 @@ import com.lframework.xingyun.sc.procurement.entity.ProcurementForeignTradeCredi @@ -23,6 +23,7 @@ import com.lframework.xingyun.sc.procurement.entity.ProcurementForeignTradeCredi
23 import com.lframework.xingyun.sc.procurement.service.credit.ProcurementDomesticCustomerCreditService; 23 import com.lframework.xingyun.sc.procurement.service.credit.ProcurementDomesticCustomerCreditService;
24 import com.lframework.xingyun.sc.procurement.service.credit.ProcurementForeignTradeCreditService; 24 import com.lframework.xingyun.sc.procurement.service.credit.ProcurementForeignTradeCreditService;
25 import com.lframework.xingyun.sc.service.contract.ContractDistributorLineService; 25 import com.lframework.xingyun.sc.service.contract.ContractDistributorLineService;
  26 +import com.lframework.xingyun.sc.service.contract.ContractChangeApplicationService;
26 import com.lframework.xingyun.sc.service.contract.ContractDistributorStandardService; 27 import com.lframework.xingyun.sc.service.contract.ContractDistributorStandardService;
27 import com.lframework.xingyun.sc.service.contract.ContractStdProcessingLineService; 28 import com.lframework.xingyun.sc.service.contract.ContractStdProcessingLineService;
28 import com.lframework.xingyun.sc.service.contract.SpecLockDelayApplicationService; 29 import com.lframework.xingyun.sc.service.contract.SpecLockDelayApplicationService;
@@ -110,6 +111,8 @@ public class BusinessDataHandlerServiceImpl implements BusinessDataHandlerServic @@ -110,6 +111,8 @@ public class BusinessDataHandlerServiceImpl implements BusinessDataHandlerServic
110 @Resource 111 @Resource
111 private SpecLockDelayApplicationService specLockDelayApplicationService; 112 private SpecLockDelayApplicationService specLockDelayApplicationService;
112 @Resource 113 @Resource
  114 + private ContractChangeApplicationService contractChangeApplicationService;
  115 + @Resource
113 private DraftRequestCarTicketService draftRequestCarTicketService; 116 private DraftRequestCarTicketService draftRequestCarTicketService;
114 @Resource 117 @Resource
115 private RequestCarTicketService requestCarTicketService; 118 private RequestCarTicketService requestCarTicketService;
@@ -208,6 +211,9 @@ public class BusinessDataHandlerServiceImpl implements BusinessDataHandlerServic @@ -208,6 +211,9 @@ public class BusinessDataHandlerServiceImpl implements BusinessDataHandlerServic
208 case "SPEC_LOCK_DELAY": 211 case "SPEC_LOCK_DELAY":
209 handleSpecLockDelayAuditData(flowStatus, businessId); 212 handleSpecLockDelayAuditData(flowStatus, businessId);
210 break; 213 break;
  214 + case "CONTRACT_CHANGE":
  215 + handleContractChangeAuditData(flowStatus, businessId);
  216 + break;
211 case "DRAFT_REQUEST_CAR": 217 case "DRAFT_REQUEST_CAR":
212 handleDraftRequestCarTicketData(flowStatus, businessId, variable); 218 handleDraftRequestCarTicketData(flowStatus, businessId, variable);
213 break; 219 break;
@@ -293,6 +299,19 @@ public class BusinessDataHandlerServiceImpl implements BusinessDataHandlerServic @@ -293,6 +299,19 @@ public class BusinessDataHandlerServiceImpl implements BusinessDataHandlerServic
293 } 299 }
294 } 300 }
295 301
  302 + private void handleContractChangeAuditData(String flowStatus, String businessId) {
  303 + if (FlowInstanceStatus.APPROVE_PASS.getCode().equals(flowStatus)
  304 + || FlowInstanceStatus.FINISH.getCode().equals(flowStatus)) {
  305 + contractChangeApplicationService.updateAuditStatus(businessId, "PASS");
  306 + } else if (FlowInstanceStatus.REVOKE.getCode().equals(flowStatus)
  307 + || FlowInstanceStatus.REFUSE.getCode().equals(flowStatus)
  308 + || FlowInstanceStatus.TERMINATION.getCode().equals(flowStatus)) {
  309 + contractChangeApplicationService.updateAuditStatus(businessId, "REFUSE");
  310 + } else if (FlowInstanceStatus.UNDO.getCode().equals(flowStatus)) {
  311 + contractChangeApplicationService.updateAuditStatus(businessId, "REFUSE");
  312 + }
  313 + }
  314 +
296 /** 315 /**
297 * 客户开发业务数据处理 316 * 客户开发业务数据处理
298 * 317 *
  1 +package com.lframework.xingyun.sc.impl.contract;
  2 +
  3 +import com.baomidou.mybatisplus.core.conditions.Wrapper;
  4 +import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  5 +import com.github.pagehelper.PageInfo;
  6 +import com.lframework.starter.bpm.dto.FlowTaskDto;
  7 +import com.lframework.starter.bpm.mappers.FlowTaskWrapperMapper;
  8 +import com.lframework.starter.bpm.service.FlowInstanceWrapperService;
  9 +import com.lframework.starter.bpm.vo.flow.task.QueryTodoTaskListVo;
  10 +import com.lframework.starter.common.exceptions.impl.DefaultClientException;
  11 +import com.lframework.starter.common.utils.Assert;
  12 +import com.lframework.starter.web.core.annotations.oplog.OpLog;
  13 +import com.lframework.starter.web.core.components.resp.PageResult;
  14 +import com.lframework.starter.web.core.components.security.SecurityUtil;
  15 +import com.lframework.starter.web.core.impl.BaseMpServiceImpl;
  16 +import com.lframework.starter.web.core.utils.IdUtil;
  17 +import com.lframework.starter.web.core.utils.JsonUtil;
  18 +import com.lframework.starter.web.core.utils.OpLogUtil;
  19 +import com.lframework.starter.web.core.utils.PageHelperUtil;
  20 +import com.lframework.starter.web.core.utils.PageResultUtil;
  21 +import com.lframework.starter.web.inner.components.oplog.OtherOpLogType;
  22 +import com.lframework.starter.web.inner.entity.SysDept;
  23 +import com.lframework.starter.web.inner.service.system.SysDeptService;
  24 +import com.lframework.xingyun.basedata.entity.Customer;
  25 +import com.lframework.xingyun.basedata.service.customer.CustomerService;
  26 +import com.lframework.xingyun.basedata.vo.customer.QueryCustomerVo;
  27 +import com.lframework.xingyun.basedata.entity.Workshop;
  28 +import com.lframework.xingyun.basedata.service.workshop.WorkshopService;
  29 +import com.lframework.xingyun.sc.entity.ContractChangeApplication;
  30 +import com.lframework.xingyun.sc.entity.ContractDistributorLine;
  31 +import com.lframework.xingyun.sc.entity.ContractDistributorStandard;
  32 +import com.lframework.xingyun.sc.entity.ContractStdProcessingLine;
  33 +import com.lframework.xingyun.sc.enums.CustomerDevelopStatus;
  34 +import com.lframework.xingyun.sc.mappers.ContractChangeApplicationMapper;
  35 +import com.lframework.xingyun.sc.mappers.ContractDistributorStandardMapper;
  36 +import com.lframework.xingyun.sc.mappers.SpecLockDelayApplicationMapper;
  37 +import com.lframework.xingyun.sc.service.contract.ContractChangeApplicationService;
  38 +import com.lframework.xingyun.sc.service.contract.ContractDistributorLineService;
  39 +import com.lframework.xingyun.sc.service.contract.ContractStdProcessingLineService;
  40 +import com.lframework.xingyun.sc.vo.contract.createVo.CreateContractChangeApplicationVo;
  41 +import com.lframework.xingyun.sc.vo.contract.queryVo.QueryContractChangeApplicationVo;
  42 +import com.lframework.xingyun.sc.vo.contract.queryVo.QueryContractChangeSelectableContractVo;
  43 +import com.lframework.xingyun.sc.vo.contract.updateVo.UpdateContractChangeApplicationVo;
  44 +import com.lframework.xingyun.sc.vo.contract.updateVo.UpdateContractDistributorLineVo;
  45 +import com.lframework.xingyun.sc.vo.contract.updateVo.UpdateContractDistributorStandardVo;
  46 +import com.lframework.xingyun.sc.vo.contract.updateVo.UpdateContractStdProcessingLineVo;
  47 +import lombok.extern.slf4j.Slf4j;
  48 +import org.apache.commons.collections4.CollectionUtils;
  49 +import org.apache.commons.lang3.StringUtils;
  50 +import org.springframework.beans.factory.annotation.Autowired;
  51 +import org.springframework.cache.annotation.CacheEvict;
  52 +import org.springframework.stereotype.Service;
  53 +import org.springframework.transaction.annotation.Transactional;
  54 +import javax.annotation.Resource;
  55 +import java.io.Serializable;
  56 +import java.util.ArrayList;
  57 +import java.util.Arrays;
  58 +import java.util.Collections;
  59 +import java.util.List;
  60 +import java.util.Map;
  61 +import java.util.Set;
  62 +import java.util.function.Function;
  63 +import java.util.stream.Collectors;
  64 +
  65 +/**
  66 + * 合同变更申请单 Service 实现
  67 + */
  68 +@Service
  69 +@Slf4j
  70 +public class ContractChangeApplicationServiceImpl extends BaseMpServiceImpl<ContractChangeApplicationMapper, ContractChangeApplication>
  71 + implements ContractChangeApplicationService {
  72 +
  73 + private static final String BPM_FLAG = "CONTRACT_CHANGE";
  74 +
  75 + @Autowired
  76 + private FlowInstanceWrapperService flowInstanceWrapperService;
  77 + @Resource
  78 + private FlowTaskWrapperMapper flowTaskWrapperMapper;
  79 + @Resource
  80 + private ContractDistributorStandardMapper contractDistributorStandardMapper;
  81 + @Resource
  82 + private ContractDistributorLineService contractDistributorLineService;
  83 + @Resource
  84 + private ContractStdProcessingLineService contractStdProcessingLineService;
  85 + @Resource
  86 + private WorkshopService workshopService;
  87 + @Resource
  88 + private SysDeptService sysDeptService;
  89 + @Resource
  90 + private CustomerService customerService;
  91 +
  92 + @Override
  93 + public PageResult<ContractChangeApplication> query(Integer pageIndex, Integer pageSize, QueryContractChangeApplicationVo vo) {
  94 + Assert.greaterThanZero(pageIndex);
  95 + Assert.greaterThanZero(pageSize);
  96 +
  97 + List<String> buyerIds = null;
  98 + List<String> contractIdsByBuyer = null;
  99 + if (StringUtils.isNotBlank(vo.getBuyerName())) {
  100 + QueryCustomerVo queryCustomerVo = new QueryCustomerVo();
  101 + queryCustomerVo.setName(vo.getBuyerName());
  102 + List<Customer> customerList = customerService.query(queryCustomerVo);
  103 + if (CollectionUtils.isEmpty(customerList)) {
  104 + return PageResultUtil.convert(new PageInfo<>(Collections.emptyList()));
  105 + }
  106 +
  107 + buyerIds = customerList.stream().map(Customer::getId).distinct().collect(Collectors.toList());
  108 + Wrapper<ContractDistributorStandard> contractWrapper = Wrappers.lambdaQuery(ContractDistributorStandard.class)
  109 + .select(ContractDistributorStandard::getId)
  110 + .in(ContractDistributorStandard::getBuyer, buyerIds);
  111 + contractIdsByBuyer = CollectionUtils.emptyIfNull(contractDistributorStandardMapper.selectList(contractWrapper))
  112 + .stream()
  113 + .map(ContractDistributorStandard::getId)
  114 + .distinct()
  115 + .collect(Collectors.toList());
  116 + }
  117 +
  118 + PageHelperUtil.startPage(pageIndex, pageSize);
  119 + com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<ContractChangeApplication> wrapper =
  120 + Wrappers.lambdaQuery(ContractChangeApplication.class)
  121 + .like(StringUtils.isNotBlank(vo.getContractCode()), ContractChangeApplication::getContractCode, vo.getContractCode())
  122 + .eq(StringUtils.isNotBlank(vo.getContractType()), ContractChangeApplication::getContractType, vo.getContractType())
  123 + .eq(StringUtils.isNotBlank(vo.getContractStage()), ContractChangeApplication::getContractStage, vo.getContractStage())
  124 + .eq(StringUtils.isNotBlank(vo.getApprovalStatus()), ContractChangeApplication::getApprovalStatus, vo.getApprovalStatus());
  125 + if (CollectionUtils.isNotEmpty(buyerIds)) {
  126 + List<String> finalBuyerIds = buyerIds;
  127 + List<String> finalContractIdsByBuyer = contractIdsByBuyer;
  128 + wrapper.and(q -> {
  129 + boolean hasCondition = false;
  130 + if (CollectionUtils.isNotEmpty(finalContractIdsByBuyer)) {
  131 + q.in(ContractChangeApplication::getContractId, finalContractIdsByBuyer);
  132 + hasCondition = true;
  133 + }
  134 + for (String buyerId : finalBuyerIds) {
  135 + if (hasCondition) {
  136 + q.or();
  137 + }
  138 + q.like(ContractChangeApplication::getAfterDataJson, "\"buyer\":\"" + buyerId + "\"");
  139 + hasCondition = true;
  140 + }
  141 + });
  142 + }
  143 + wrapper.orderByDesc(ContractChangeApplication::getCreateTime);
  144 + List<ContractChangeApplication> datas = list(wrapper);
  145 + fillDisplayInfo(datas);
  146 + fillShowExamine(datas);
  147 + return PageResultUtil.convert(new PageInfo<>(datas));
  148 + }
  149 +
  150 + @Override
  151 + public ContractChangeApplication findById(String id) {
  152 + ContractChangeApplication data = getBaseMapper().selectById(id);
  153 + if (data == null) {
  154 + return null;
  155 + }
  156 + fillDisplayInfo(Collections.singletonList(data));
  157 + fillShowExamine(Arrays.asList(data));
  158 + return data;
  159 + }
  160 +
  161 + @Override
  162 + @Transactional(rollbackFor = Exception.class)
  163 + @OpLog(type = OtherOpLogType.class, name = "新增合同变更申请单,ID:{}", params = {"#id"})
  164 + public String create(CreateContractChangeApplicationVo vo) throws Exception {
  165 + ContractDistributorStandard contract = getContractOrThrow(vo.getContractId());
  166 + validateContractCanChange(contract);
  167 +
  168 + UpdateContractDistributorStandardVo beforeData = buildContractData(contract);
  169 + UpdateContractDistributorStandardVo afterData = normalizeContractData(contract, vo.getContractData(), vo.getChangeReason());
  170 +
  171 + ContractChangeApplication data = new ContractChangeApplication();
  172 + data.setId(IdUtil.getUUID());
  173 + data.setContractId(contract.getId());
  174 + data.setRootContractId(getRootContractId(contract));
  175 + data.setContractCode(contract.getCode());
  176 + data.setContractType(contract.getType());
  177 + data.setContractStage(contract.getStatus());
  178 + data.setChangeReason(StringUtils.defaultIfBlank(vo.getChangeReason(), afterData.getChangeReason()));
  179 + data.setBeforeDataJson(JsonUtil.toJsonString(beforeData));
  180 + data.setAfterDataJson(JsonUtil.toJsonString(afterData));
  181 + data.setApprovalStatus(CustomerDevelopStatus.AUDIT.name());
  182 +
  183 + fillFlowVariables(data, contract, afterData);
  184 + getBaseMapper().insert(data);
  185 +
  186 + OpLogUtil.setVariable("id", data.getId());
  187 + OpLogUtil.setExtra(vo);
  188 +
  189 + data.setCreateById(SecurityUtil.getCurrentUser().getId());
  190 + flowInstanceWrapperService.startInstance(BPM_FLAG, data.getId(), BPM_FLAG, data);
  191 + return data.getId();
  192 + }
  193 +
  194 + @Override
  195 + @Transactional(rollbackFor = Exception.class)
  196 + @OpLog(type = OtherOpLogType.class, name = "修改合同变更申请单,ID:{}", params = {"#vo.id"})
  197 + public void update(UpdateContractChangeApplicationVo vo) throws Exception {
  198 + ContractChangeApplication data = getBaseMapper().selectById(vo.getId());
  199 + if (data == null) {
  200 + throw new DefaultClientException("合同变更申请单不存在!");
  201 + }
  202 + if (!CustomerDevelopStatus.REFUSE.name().equals(data.getApprovalStatus())) {
  203 + throw new DefaultClientException(CustomerDevelopStatus.getDescByNameSafe(data.getApprovalStatus()) + "的合同变更申请单不允许修改!");
  204 + }
  205 +
  206 + ContractDistributorStandard contract = getContractOrThrow(data.getContractId());
  207 + UpdateContractDistributorStandardVo afterData = normalizeContractData(contract, vo.getContractData(), vo.getChangeReason());
  208 +
  209 + Wrapper<ContractChangeApplication> wrapper = Wrappers.lambdaUpdate(ContractChangeApplication.class)
  210 + .set(ContractChangeApplication::getChangeReason, StringUtils.defaultIfBlank(vo.getChangeReason(), afterData.getChangeReason()))
  211 + .set(ContractChangeApplication::getAfterDataJson, JsonUtil.toJsonString(afterData))
  212 + .set(ContractChangeApplication::getApprovalStatus, CustomerDevelopStatus.AUDIT.name())
  213 + .eq(ContractChangeApplication::getId, vo.getId());
  214 + update(wrapper);
  215 +
  216 + fillFlowVariables(data, contract, afterData);
  217 + data.setAfterDataJson(JsonUtil.toJsonString(afterData));
  218 + data.setChangeReason(StringUtils.defaultIfBlank(vo.getChangeReason(), afterData.getChangeReason()));
  219 + flowInstanceWrapperService.startInstance(BPM_FLAG, data.getId(), BPM_FLAG, data);
  220 +
  221 + OpLogUtil.setVariable("id", data.getId());
  222 + OpLogUtil.setExtra(vo);
  223 + cleanCacheByKey(data.getId());
  224 + }
  225 +
  226 + @Override
  227 + @Transactional(rollbackFor = Exception.class)
  228 + @OpLog(type = OtherOpLogType.class, name = "取消合同变更申请单,ID:{}", params = {"#id"})
  229 + public void cancelApplication(String id) {
  230 + ContractChangeApplication data = getBaseMapper().selectById(id);
  231 + if (data == null) {
  232 + throw new DefaultClientException("合同变更申请单不存在!");
  233 + }
  234 + if (CustomerDevelopStatus.CANCEL.name().equals(data.getApprovalStatus())) {
  235 + throw new DefaultClientException("合同变更申请单已取消!");
  236 + }
  237 + if (!CustomerDevelopStatus.REFUSE.name().equals(data.getApprovalStatus())) {
  238 + throw new DefaultClientException(CustomerDevelopStatus.getDescByNameSafe(data.getApprovalStatus()) + "的合同变更申请单不允许取消!");
  239 + }
  240 +
  241 + Wrapper<ContractChangeApplication> wrapper = Wrappers.lambdaUpdate(ContractChangeApplication.class)
  242 + .set(ContractChangeApplication::getApprovalStatus, CustomerDevelopStatus.CANCEL.name())
  243 + .eq(ContractChangeApplication::getId, id);
  244 + update(wrapper);
  245 +
  246 + cleanCacheByKey(id);
  247 + }
  248 +
  249 + @Override
  250 + @Transactional(rollbackFor = Exception.class)
  251 + @OpLog(type = OtherOpLogType.class, name = "合同变更申请单审批完成,ID:{},审批状态:{}", params = {"#id", "#approvalStatus"})
  252 + public void updateAuditStatus(String id, String approvalStatus) {
  253 + if (StringUtils.isBlank(id) || StringUtils.isBlank(approvalStatus)) {
  254 + return;
  255 + }
  256 +
  257 + ContractChangeApplication data = getBaseMapper().selectById(id);
  258 + if (data == null) {
  259 + return;
  260 + }
  261 +
  262 + Wrapper<ContractChangeApplication> wrapper = Wrappers.lambdaUpdate(ContractChangeApplication.class)
  263 + .set(ContractChangeApplication::getApprovalStatus, approvalStatus)
  264 + .eq(ContractChangeApplication::getId, id);
  265 + update(wrapper);
  266 +
  267 + if (CustomerDevelopStatus.PASS.name().equals(approvalStatus)) {
  268 + applyContractChange(data);
  269 + }
  270 +
  271 + cleanCacheByKey(id);
  272 + }
  273 +
  274 + @Override
  275 + public PageResult<ContractDistributorStandard> querySelectableContracts(Integer pageIndex, Integer pageSize,
  276 + QueryContractChangeSelectableContractVo vo) {
  277 + Assert.greaterThanZero(pageIndex);
  278 + Assert.greaterThanZero(pageSize);
  279 +
  280 + PageHelperUtil.startPage(pageIndex, pageSize);
  281 + List<ContractDistributorStandard> datas = getBaseMapper().querySelectableContracts(vo);
  282 + return PageResultUtil.convert(new PageInfo<>(datas));
  283 + }
  284 +
  285 + @Override
  286 + public boolean hasUnfinishedApplication(String rootContractId) {
  287 + if (StringUtils.isBlank(rootContractId)) {
  288 + return false;
  289 + }
  290 + Wrapper<ContractChangeApplication> wrapper = Wrappers.lambdaQuery(ContractChangeApplication.class)
  291 + .eq(ContractChangeApplication::getRootContractId, rootContractId)
  292 + .notIn(ContractChangeApplication::getApprovalStatus,
  293 + Arrays.asList(CustomerDevelopStatus.PASS.name(), CustomerDevelopStatus.CANCEL.name()));
  294 + return count(wrapper) > 0;
  295 + }
  296 +
  297 + @CacheEvict(value = ContractChangeApplication.CACHE_NAME, key = "@cacheVariables.tenantId() + #key")
  298 + @Override
  299 + public void cleanCacheByKey(Serializable key) {
  300 + }
  301 +
  302 + /**
  303 + * 填充审核待办标识
  304 + *
  305 + * @param datas 数据列表
  306 + */
  307 + private void fillShowExamine(List<ContractChangeApplication> datas) {
  308 + if (CollectionUtils.isEmpty(datas)) {
  309 + return;
  310 + }
  311 +
  312 + List<FlowTaskDto> flowTaskList = flowTaskWrapperMapper.queryTodoList(new QueryTodoTaskListVo(),
  313 + SecurityUtil.getCurrentUser().getId());
  314 + if (CollectionUtils.isEmpty(flowTaskList)) {
  315 + datas.forEach(item -> item.setShowExamine(false));
  316 + return;
  317 + }
  318 +
  319 + Set<String> ids = flowTaskList.stream()
  320 + .filter(task -> BPM_FLAG.equals(task.getMode()))
  321 + .map(FlowTaskDto::getBusinessId)
  322 + .collect(Collectors.toSet());
  323 + datas.forEach(item -> item.setShowExamine(ids.contains(item.getId())));
  324 + }
  325 +
  326 + /**
  327 + * 填充列表展示信息
  328 + *
  329 + * @param datas 申请单列表
  330 + */
  331 + private void fillDisplayInfo(List<ContractChangeApplication> datas) {
  332 + if (CollectionUtils.isEmpty(datas)) {
  333 + return;
  334 + }
  335 +
  336 + Map<String, UpdateContractDistributorStandardVo> afterDataMap = datas.stream()
  337 + .filter(item -> StringUtils.isNotBlank(item.getAfterDataJson()))
  338 + .collect(Collectors.toMap(ContractChangeApplication::getId,
  339 + item -> JsonUtil.parseObject(item.getAfterDataJson(), UpdateContractDistributorStandardVo.class)));
  340 +
  341 + List<String> contractIds = datas.stream()
  342 + .filter(item -> !afterDataMap.containsKey(item.getId()))
  343 + .map(ContractChangeApplication::getContractId)
  344 + .filter(StringUtils::isNotBlank)
  345 + .distinct()
  346 + .collect(Collectors.toList());
  347 + final Map<String, ContractDistributorStandard> contractMap;
  348 + if (CollectionUtils.isNotEmpty(contractIds)) {
  349 + Wrapper<ContractDistributorStandard> contractWrapper = Wrappers.lambdaQuery(ContractDistributorStandard.class)
  350 + .select(ContractDistributorStandard::getId, ContractDistributorStandard::getDeptId,
  351 + ContractDistributorStandard::getWorkshopId, ContractDistributorStandard::getBuyer,
  352 + ContractDistributorStandard::getTotalAmountIncludingTax, ContractDistributorStandard::getTotalQuantity)
  353 + .in(ContractDistributorStandard::getId, contractIds);
  354 + contractMap = CollectionUtils.emptyIfNull(contractDistributorStandardMapper.selectList(contractWrapper))
  355 + .stream()
  356 + .collect(Collectors.toMap(ContractDistributorStandard::getId, Function.identity()));
  357 + } else {
  358 + contractMap = Collections.emptyMap();
  359 + }
  360 +
  361 + List<String> deptIds = new ArrayList<>();
  362 + List<String> workshopIds = new ArrayList<>();
  363 + List<String> customerIds = new ArrayList<>();
  364 + datas.forEach(item -> {
  365 + UpdateContractDistributorStandardVo afterData = afterDataMap.get(item.getId());
  366 + if (afterData != null) {
  367 + if (StringUtils.isNotBlank(afterData.getDeptId())) {
  368 + deptIds.add(afterData.getDeptId());
  369 + }
  370 + if (StringUtils.isNotBlank(afterData.getWorkshopId())) {
  371 + workshopIds.add(afterData.getWorkshopId());
  372 + }
  373 + if (StringUtils.isNotBlank(afterData.getBuyer())) {
  374 + customerIds.add(afterData.getBuyer());
  375 + }
  376 + return;
  377 + }
  378 +
  379 + ContractDistributorStandard contract = contractMap.get(item.getContractId());
  380 + if (contract != null) {
  381 + if (StringUtils.isNotBlank(contract.getDeptId())) {
  382 + deptIds.add(contract.getDeptId());
  383 + }
  384 + if (StringUtils.isNotBlank(contract.getWorkshopId())) {
  385 + workshopIds.add(contract.getWorkshopId());
  386 + }
  387 + if (StringUtils.isNotBlank(contract.getBuyer())) {
  388 + customerIds.add(contract.getBuyer());
  389 + }
  390 + }
  391 + });
  392 +
  393 + Map<String, SysDept> deptMap = CollectionUtils.emptyIfNull(sysDeptService.listByIds(deptIds.stream().distinct().collect(Collectors.toList())))
  394 + .stream()
  395 + .collect(Collectors.toMap(SysDept::getId, Function.identity()));
  396 + Map<String, Workshop> workshopMap = CollectionUtils.emptyIfNull(workshopService.listByIds(workshopIds.stream().distinct().collect(Collectors.toList())))
  397 + .stream()
  398 + .collect(Collectors.toMap(Workshop::getId, Function.identity()));
  399 + Map<String, Customer> customerMap = CollectionUtils.emptyIfNull(customerService.listByIds(customerIds.stream().distinct().collect(Collectors.toList())))
  400 + .stream()
  401 + .collect(Collectors.toMap(Customer::getId, Function.identity()));
  402 +
  403 + datas.forEach(item -> {
  404 + String deptId = null;
  405 + String workshopId = null;
  406 + String buyerId = null;
  407 +
  408 + UpdateContractDistributorStandardVo afterData = afterDataMap.get(item.getId());
  409 + if (afterData != null) {
  410 + deptId = afterData.getDeptId();
  411 + workshopId = afterData.getWorkshopId();
  412 + buyerId = afterData.getBuyer();
  413 + item.setTotalAmountIncludingTax(afterData.getTotalAmountIncludingTax());
  414 + item.setTotalQuantity(afterData.getTotalQuantity());
  415 + } else {
  416 + ContractDistributorStandard contract = contractMap.get(item.getContractId());
  417 + if (contract != null) {
  418 + deptId = contract.getDeptId();
  419 + workshopId = contract.getWorkshopId();
  420 + buyerId = contract.getBuyer();
  421 + item.setTotalAmountIncludingTax(contract.getTotalAmountIncludingTax());
  422 + item.setTotalQuantity(contract.getTotalQuantity());
  423 + }
  424 + }
  425 +
  426 + SysDept dept = deptMap.get(deptId);
  427 + if (dept != null) {
  428 + item.setDeptCode(dept.getCode());
  429 + item.setDeptCodeName(dept.getName());
  430 + }
  431 +
  432 + Workshop workshop = workshopMap.get(workshopId);
  433 + if (workshop != null) {
  434 + item.setWorkshopCode(workshop.getCode());
  435 + item.setWorkshopName(workshop.getName());
  436 + }
  437 +
  438 + Customer customer = customerMap.get(buyerId);
  439 + if (customer != null) {
  440 + item.setBuyerName(customer.getName());
  441 + }
  442 + });
  443 + }
  444 +
  445 + /**
  446 + * 获取合同,不存在则抛异常
  447 + *
  448 + * @param contractId 合同ID
  449 + * @return 合同
  450 + */
  451 + private ContractDistributorStandard getContractOrThrow(String contractId) {
  452 + ContractDistributorStandard contract = contractDistributorStandardMapper.selectById(contractId);
  453 + if (contract == null) {
  454 + throw new DefaultClientException("合同不存在!");
  455 + }
  456 + return contract;
  457 + }
  458 +
  459 + /**
  460 + * 校验合同是否允许发起变更
  461 + *
  462 + * @param contract 合同
  463 + */
  464 + private void validateContractCanChange(ContractDistributorStandard contract) {
  465 + if (contract == null) {
  466 + throw new DefaultClientException("合同不存在!");
  467 + }
  468 + if (!isSupportedChangeContract(contract)) {
  469 + throw new DefaultClientException("该合同当前不允许发起变更!");
  470 + }
  471 +
  472 + String rootContractId = getRootContractId(contract);
  473 + if (hasUnfinishedApplication(rootContractId)) {
  474 + throw new DefaultClientException("该合同存在未结束的合同变更流程,不允许重复发起变更!");
  475 + }
  476 + }
  477 +
  478 + /**
  479 + * 判断是否为支持发起变更的合同
  480 + *
  481 + * @param contract 合同
  482 + * @return 是否支持
  483 + */
  484 + private boolean isSupportedChangeContract(ContractDistributorStandard contract) {
  485 + if (contract == null || StringUtils.isBlank(contract.getType()) || StringUtils.isBlank(contract.getStatus())) {
  486 + return false;
  487 + }
  488 +
  489 + if ("DISTRIB_STD".equals(contract.getType())
  490 + || "DRAFT_DIST_AGMT".equals(contract.getType())
  491 + || "INTL_STD_CONTRACT".equals(contract.getType())
  492 + || "INTL_OPEN_SPEC_AGMT".equals(contract.getType())
  493 + || "PROCESS_STD_AGMT".equals(contract.getType())) {
  494 + return "STANDARD".equals(contract.getStatus()) && CustomerDevelopStatus.PASS.name().equals(contract.getStandardApproved());
  495 + }
  496 +
  497 + if ("DIST_STOCK_CONTRACT".equals(contract.getType()) || "INTL_INVENTORY_AGMT".equals(contract.getType())) {
  498 + if ("FORMAL".equals(contract.getStatus())) {
  499 + return CustomerDevelopStatus.PASS.name().equals(contract.getFormalApproved());
  500 + }
  501 + if ("STANDARD".equals(contract.getStatus())) {
  502 + return CustomerDevelopStatus.PASS.name().equals(contract.getStandardApproved());
  503 + }
  504 + }
  505 + return false;
  506 + }
  507 +
  508 + /**
  509 + * 构建合同变更数据快照
  510 + *
  511 + * @param contract 合同
  512 + * @return 合同变更数据
  513 + */
  514 + private UpdateContractDistributorStandardVo buildContractData(ContractDistributorStandard contract) {
  515 + UpdateContractDistributorStandardVo result = JsonUtil.parseObject(JsonUtil.toJsonString(contract),
  516 + UpdateContractDistributorStandardVo.class);
  517 +
  518 + Wrapper<ContractDistributorLine> distributorLineWrapper = Wrappers.lambdaQuery(ContractDistributorLine.class)
  519 + .eq(ContractDistributorLine::getContractId, contract.getId())
  520 + .orderByAsc(ContractDistributorLine::getShowOrder);
  521 + List<ContractDistributorLine> distributorLineList = contractDistributorLineService.list(distributorLineWrapper);
  522 + if (CollectionUtils.isNotEmpty(distributorLineList)) {
  523 + result.setContractDistributorLineList(JsonUtil.parseList(JsonUtil.toJsonString(distributorLineList),
  524 + UpdateContractDistributorLineVo.class));
  525 + } else {
  526 + result.setContractDistributorLineList(new ArrayList<>());
  527 + }
  528 +
  529 + Wrapper<ContractStdProcessingLine> processingLineWrapper = Wrappers.lambdaQuery(ContractStdProcessingLine.class)
  530 + .eq(ContractStdProcessingLine::getContractId, contract.getId())
  531 + .orderByAsc(ContractStdProcessingLine::getShowOrder);
  532 + List<ContractStdProcessingLine> processingLineList = contractStdProcessingLineService.list(processingLineWrapper);
  533 + if (CollectionUtils.isNotEmpty(processingLineList)) {
  534 + result.setContractStdProcessingLineList(JsonUtil.parseList(JsonUtil.toJsonString(processingLineList),
  535 + UpdateContractStdProcessingLineVo.class));
  536 + } else {
  537 + result.setContractStdProcessingLineList(new ArrayList<>());
  538 + }
  539 + return result;
  540 + }
  541 +
  542 + /**
  543 + * 规范化变更后的合同数据
  544 + *
  545 + * @param contract 原合同
  546 + * @param contractData 变更后的合同数据
  547 + * @param changeReason 变更原因
  548 + * @return 规范化后的合同数据
  549 + */
  550 + private UpdateContractDistributorStandardVo normalizeContractData(ContractDistributorStandard contract,
  551 + UpdateContractDistributorStandardVo contractData,
  552 + String changeReason) {
  553 + if (contractData == null) {
  554 + throw new DefaultClientException("变更后的合同数据不能为空!");
  555 + }
  556 +
  557 + UpdateContractDistributorStandardVo result = JsonUtil.parseObject(JsonUtil.toJsonString(contractData),
  558 + UpdateContractDistributorStandardVo.class);
  559 + result.setId(contract.getId());
  560 + result.setType(contract.getType());
  561 + result.setStatus(contract.getStatus());
  562 + result.setParentId(contract.getParentId());
  563 + result.setChangeReason(StringUtils.defaultIfBlank(changeReason, result.getChangeReason()));
  564 + if (result.getContractDistributorLineList() == null) {
  565 + result.setContractDistributorLineList(new ArrayList<>());
  566 + }
  567 + if (result.getContractStdProcessingLineList() == null) {
  568 + result.setContractStdProcessingLineList(new ArrayList<>());
  569 + }
  570 + return result;
  571 + }
  572 +
  573 + /**
  574 + * 填充流程变量
  575 + *
  576 + * @param data 申请单
  577 + * @param contract 合同
  578 + * @param afterData 变更后数据
  579 + */
  580 + private void fillFlowVariables(ContractChangeApplication data, ContractDistributorStandard contract,
  581 + UpdateContractDistributorStandardVo afterData) {
  582 + if (data == null || contract == null) {
  583 + return;
  584 + }
  585 +
  586 + String workshopId = afterData == null || StringUtils.isBlank(afterData.getWorkshopId())
  587 + ? contract.getWorkshopId()
  588 + : afterData.getWorkshopId();
  589 + String deptId = afterData == null || StringUtils.isBlank(afterData.getDeptId())
  590 + ? contract.getDeptId()
  591 + : afterData.getDeptId();
  592 +
  593 + Workshop workshop = workshopService.findById(workshopId);
  594 + data.setWorkshopCode(workshop == null ? "" : workshop.getCode());
  595 + SysDept sysDept = sysDeptService.findById(deptId);
  596 + data.setDeptCode(sysDept == null ? "" : sysDept.getCode());
  597 + }
  598 +
  599 + /**
  600 + * 获取根合同ID
  601 + *
  602 + * @param contract 合同
  603 + * @return 根合同ID
  604 + */
  605 + private String getRootContractId(ContractDistributorStandard contract) {
  606 + if (contract == null) {
  607 + return null;
  608 + }
  609 + return StringUtils.isBlank(contract.getParentId()) ? contract.getId() : contract.getParentId();
  610 + }
  611 +
  612 + /**
  613 + * 应用合同变更
  614 + *
  615 + * @param application 变更申请单
  616 + */
  617 + private void applyContractChange(ContractChangeApplication application) {
  618 + if (application == null || StringUtils.isBlank(application.getAfterDataJson())) {
  619 + return;
  620 + }
  621 +
  622 + UpdateContractDistributorStandardVo vo = JsonUtil.parseObject(application.getAfterDataJson(),
  623 + UpdateContractDistributorStandardVo.class);
  624 + ContractDistributorStandard data = contractDistributorStandardMapper.selectById(application.getContractId());
  625 + if (data == null) {
  626 + throw new DefaultClientException("对应合同不存在!");
  627 + }
  628 +
  629 + Wrapper<ContractDistributorStandard> wrapper = Wrappers.lambdaUpdate(ContractDistributorStandard.class)
  630 + .set(ContractDistributorStandard::getCode, vo.getCode())
  631 + .set(ContractDistributorStandard::getSupplier, vo.getSupplier())
  632 + .set(ContractDistributorStandard::getBuyer, vo.getBuyer())
  633 + .set(ContractDistributorStandard::getDeptId, vo.getDeptId())
  634 + .set(ContractDistributorStandard::getRegion, vo.getRegion())
  635 + .set(ContractDistributorStandard::getStockUpCompanyId, vo.getStockUpCompanyId())
  636 + .set(ContractDistributorStandard::getOrderDate, vo.getOrderDate())
  637 + .set(ContractDistributorStandard::getUnit, vo.getUnit())
  638 + .set(ContractDistributorStandard::getWorkshopId, vo.getWorkshopId())
  639 + .set(ContractDistributorStandard::getTotalAmountCapital, vo.getTotalAmountCapital())
  640 + .set(ContractDistributorStandard::getDepositInfo, vo.getDepositInfo())
  641 + .set(ContractDistributorStandard::getPackagingRequirements, vo.getPackagingRequirements())
  642 + .set(ContractDistributorStandard::getPaymentTerms, vo.getPaymentTerms())
  643 + .set(ContractDistributorStandard::getExecutionStandard, vo.getExecutionStandard())
  644 + .set(ContractDistributorStandard::getExecutionStandardRemarks, vo.getExecutionStandardRemarks())
  645 + .set(ContractDistributorStandard::getTransportMode, vo.getTransportMode())
  646 + .set(ContractDistributorStandard::getDestination, vo.getDestination())
  647 + .set(ContractDistributorStandard::getForeignDestination, vo.getForeignDestination())
  648 + .set(ContractDistributorStandard::getIncludesPackagingFee, vo.getIncludesPackagingFee())
  649 + .set(ContractDistributorStandard::getIncludesTransportFee, vo.getIncludesTransportFee())
  650 + .set(ContractDistributorStandard::getPieceWeightHead, vo.getPieceWeightHead())
  651 + .set(ContractDistributorStandard::getSurface, vo.getSurface())
  652 + .set(ContractDistributorStandard::getTolerance, vo.getTolerance())
  653 + .set(ContractDistributorStandard::getPerformance, vo.getPerformance())
  654 + .set(ContractDistributorStandard::getComponent, vo.getComponent())
  655 + .set(ContractDistributorStandard::getPackaging, vo.getPackaging())
  656 + .set(ContractDistributorStandard::getSpecialTerms, vo.getSpecialTerms())
  657 + .set(ContractDistributorStandard::getDesignatedConsignee, vo.getDesignatedConsignee())
  658 + .set(ContractDistributorStandard::getSpecialInstructions, vo.getSpecialInstructions())
  659 + .set(ContractDistributorStandard::getRemarks, vo.getRemarks())
  660 + .set(ContractDistributorStandard::getFormalFileId, vo.getFormalFileId())
  661 + .set(ContractDistributorStandard::getFormalFileName, vo.getFormalFileName())
  662 + .set(ContractDistributorStandard::getFormalStandardized, vo.getFormalStandardized())
  663 + .set(ContractDistributorStandard::getStandardFileId, vo.getStandardFileId())
  664 + .set(ContractDistributorStandard::getStandardFileName, vo.getStandardFileName())
  665 + .set(ContractDistributorStandard::getStandardStandardized, vo.getStandardStandardized())
  666 + .set(ContractDistributorStandard::getTotalQuantity, vo.getTotalQuantity())
  667 + .set(ContractDistributorStandard::getTotalAmountExcludingTax, vo.getTotalAmountExcludingTax())
  668 + .set(ContractDistributorStandard::getTotalAmountIncludingTax, vo.getTotalAmountIncludingTax())
  669 + .set(ContractDistributorStandard::getChangeReason, vo.getChangeReason())
  670 + .set(ContractDistributorStandard::getChanged, true)
  671 + .eq(ContractDistributorStandard::getId, application.getContractId());
  672 + contractDistributorStandardMapper.update(wrapper);
  673 +
  674 + overwriteDistributorLines(application.getContractId(), vo);
  675 + overwriteProcessingLines(application.getContractId(), vo);
  676 + }
  677 +
  678 + /**
  679 + * 覆盖普通合同行
  680 + *
  681 + * @param contractId 合同ID
  682 + * @param vo 合同数据
  683 + */
  684 + private void overwriteDistributorLines(String contractId, UpdateContractDistributorStandardVo vo) {
  685 + if (CollectionUtils.isEmpty(vo.getContractDistributorLineList())) {
  686 + return;
  687 + }
  688 +
  689 + for (int i = 0; i < vo.getContractDistributorLineList().size(); i++) {
  690 + UpdateContractDistributorLineVo lineVo = vo.getContractDistributorLineList().get(i);
  691 + if (StringUtils.isBlank(lineVo.getId())) {
  692 + throw new DefaultClientException("合同变更后的普通合同行存在缺少ID的数据,不允许新增或删除物料行!");
  693 + }
  694 +
  695 + ContractDistributorLine line = contractDistributorLineService.findById(lineVo.getId());
  696 + if (line == null || !StringUtils.equals(contractId, line.getContractId())) {
  697 + throw new DefaultClientException("合同变更后的普通合同行数据异常,存在不属于当前合同的物料行!");
  698 + }
  699 +
  700 + lineVo.setContractId(contractId);
  701 + lineVo.setShowOrder(i);
  702 + contractDistributorLineService.update(lineVo);
  703 + }
  704 + }
  705 +
  706 + /**
  707 + * 覆盖加工合同行
  708 + *
  709 + * @param contractId 合同ID
  710 + * @param vo 合同数据
  711 + */
  712 + private void overwriteProcessingLines(String contractId, UpdateContractDistributorStandardVo vo) {
  713 + if (CollectionUtils.isEmpty(vo.getContractStdProcessingLineList())) {
  714 + return;
  715 + }
  716 +
  717 + for (int i = 0; i < vo.getContractStdProcessingLineList().size(); i++) {
  718 + UpdateContractStdProcessingLineVo lineVo = vo.getContractStdProcessingLineList().get(i);
  719 + if (StringUtils.isBlank(lineVo.getId())) {
  720 + throw new DefaultClientException("合同变更后的加工合同行存在缺少ID的数据,不允许新增或删除物料行!");
  721 + }
  722 +
  723 + ContractStdProcessingLine line = contractStdProcessingLineService.findById(lineVo.getId());
  724 + if (line == null || !StringUtils.equals(contractId, line.getContractId())) {
  725 + throw new DefaultClientException("合同变更后的加工合同行数据异常,存在不属于当前合同的物料行!");
  726 + }
  727 +
  728 + lineVo.setContractId(contractId);
  729 + lineVo.setShowOrder(i);
  730 + contractStdProcessingLineService.update(lineVo);
  731 + }
  732 + }
  733 +}
@@ -35,7 +35,9 @@ import com.lframework.starter.common.utils.ObjectUtil; @@ -35,7 +35,9 @@ import com.lframework.starter.common.utils.ObjectUtil;
35 import com.lframework.starter.common.utils.Assert; 35 import com.lframework.starter.common.utils.Assert;
36 import com.lframework.xingyun.sc.enums.CustomerDevelopStatus; 36 import com.lframework.xingyun.sc.enums.CustomerDevelopStatus;
37 import com.lframework.xingyun.sc.handlers.TransactorHandler; 37 import com.lframework.xingyun.sc.handlers.TransactorHandler;
  38 +import com.lframework.xingyun.sc.mappers.SpecLockDelayApplicationMapper;
38 import com.lframework.xingyun.sc.mappers.ContractDistributorStandardMapper; 39 import com.lframework.xingyun.sc.mappers.ContractDistributorStandardMapper;
  40 +import com.lframework.xingyun.sc.service.contract.ContractChangeApplicationService;
39 import com.lframework.xingyun.sc.service.contract.ContractDistributorLineService; 41 import com.lframework.xingyun.sc.service.contract.ContractDistributorLineService;
40 import com.lframework.xingyun.sc.service.contract.ContractDistributorStandardService; 42 import com.lframework.xingyun.sc.service.contract.ContractDistributorStandardService;
41 import com.lframework.xingyun.sc.service.contract.ContractFrameworkService; 43 import com.lframework.xingyun.sc.service.contract.ContractFrameworkService;
@@ -110,6 +112,10 @@ public class ContractDistributorStandardServiceImpl extends @@ -110,6 +112,10 @@ public class ContractDistributorStandardServiceImpl extends
110 private PurchaseOrderLineService purchaseOrderLineService; 112 private PurchaseOrderLineService purchaseOrderLineService;
111 @Resource 113 @Resource
112 private TransactorHandler transactorHandler; 114 private TransactorHandler transactorHandler;
  115 + @Resource
  116 + private ContractChangeApplicationService contractChangeApplicationService;
  117 + @Resource
  118 + private SpecLockDelayApplicationMapper specLockDelayApplicationMapper;
113 119
114 @Override 120 @Override
115 public PageResult<ContractDistributorStandard> query(Integer pageIndex, Integer pageSize, QueryContractDistributorStandardVo vo) { 121 public PageResult<ContractDistributorStandard> query(Integer pageIndex, Integer pageSize, QueryContractDistributorStandardVo vo) {
@@ -219,6 +225,7 @@ public class ContractDistributorStandardServiceImpl extends @@ -219,6 +225,7 @@ public class ContractDistributorStandardServiceImpl extends
219 225
220 List<ContractDistributorStandard> datas = getBaseMapper().query(vo); 226 List<ContractDistributorStandard> datas = getBaseMapper().query(vo);
221 CollectionUtils.emptyIfNull(datas).forEach(data -> data.setCanSplit(isCanSplit(data))); 227 CollectionUtils.emptyIfNull(datas).forEach(data -> data.setCanSplit(isCanSplit(data)));
  228 + fillCanPriceLock(datas);
222 return datas; 229 return datas;
223 } 230 }
224 231
@@ -239,6 +246,7 @@ public class ContractDistributorStandardServiceImpl extends @@ -239,6 +246,7 @@ public class ContractDistributorStandardServiceImpl extends
239 } 246 }
240 data.setCanEdit(canEdit); 247 data.setCanEdit(canEdit);
241 fillRemainingQuantity(data); 248 fillRemainingQuantity(data);
  249 + fillCanPriceLock(data);
242 250
243 // 获取当前人员的待办任务数据 251 // 获取当前人员的待办任务数据
244 List<FlowTaskDto> flowTaskList = flowTaskWrapperMapper.queryTodoList(new QueryTodoTaskListVo(), SecurityUtil.getCurrentUser().getId()); 252 List<FlowTaskDto> flowTaskList = flowTaskWrapperMapper.queryTodoList(new QueryTodoTaskListVo(), SecurityUtil.getCurrentUser().getId());
@@ -308,6 +316,73 @@ public class ContractDistributorStandardServiceImpl extends @@ -308,6 +316,73 @@ public class ContractDistributorStandardServiceImpl extends
308 return true; 316 return true;
309 } 317 }
310 318
  319 + /**
  320 + * 批量回填是否可锁价
  321 + *
  322 + * @param datas 合同列表
  323 + */
  324 + private void fillCanPriceLock(List<ContractDistributorStandard> datas) {
  325 + if (CollectionUtils.isEmpty(datas)) {
  326 + return;
  327 + }
  328 +
  329 + List<ContractDistributorStandard> inventoryContracts = CollectionUtils.emptyIfNull(datas).stream()
  330 + .filter(Objects::nonNull)
  331 + .filter(this::isInventoryContract)
  332 + .collect(Collectors.toList());
  333 + if (CollectionUtils.isEmpty(inventoryContracts)) {
  334 + CollectionUtils.emptyIfNull(datas).stream()
  335 + .filter(Objects::nonNull)
  336 + .forEach(data -> data.setCanPriceLock(false));
  337 + return;
  338 + }
  339 +
  340 + CollectionUtils.emptyIfNull(datas).stream()
  341 + .filter(Objects::nonNull)
  342 + .forEach(data -> data.setCanPriceLock(
  343 + isCanPriceLock(data)));
  344 + }
  345 +
  346 + /**
  347 + * 回填是否可锁价
  348 + *
  349 + * @param data 合同
  350 + */
  351 + private void fillCanPriceLock(ContractDistributorStandard data) {
  352 + if (data == null || StringUtils.isBlank(data.getId())) {
  353 + return;
  354 + }
  355 +
  356 + data.setCanPriceLock(isCanPriceLock(data));
  357 + }
  358 +
  359 + /**
  360 + * 判断是否可锁价
  361 + *
  362 + * @param data 合同
  363 + * @return 是否可锁价
  364 + */
  365 + private boolean isCanPriceLock(ContractDistributorStandard data) {
  366 + if (!isInventoryContract(data)) {
  367 + return false;
  368 + }
  369 + if (Boolean.TRUE.equals(data.getPriceSpecLocked())) {
  370 + return false;
  371 + }
  372 + return true;
  373 + }
  374 +
  375 + /**
  376 + * 判断是否为库存合同
  377 + *
  378 + * @param data 合同
  379 + * @return 是否为库存合同
  380 + */
  381 + private boolean isInventoryContract(ContractDistributorStandard data) {
  382 + return data != null && ("DIST_STOCK_CONTRACT".equals(data.getType())
  383 + || "INTL_INVENTORY_AGMT".equals(data.getType()));
  384 + }
  385 +
311 @OpLog(type = OtherOpLogType.class, name = "新增合同,ID:{}", params = {"#id"}) 386 @OpLog(type = OtherOpLogType.class, name = "新增合同,ID:{}", params = {"#id"})
312 @Transactional(rollbackFor = Exception.class) 387 @Transactional(rollbackFor = Exception.class)
313 @Override 388 @Override
@@ -1292,6 +1367,10 @@ public class ContractDistributorStandardServiceImpl extends @@ -1292,6 +1367,10 @@ public class ContractDistributorStandardServiceImpl extends
1292 throw new DefaultClientException("合同不存在!"); 1367 throw new DefaultClientException("合同不存在!");
1293 } 1368 }
1294 1369
  1370 + if(hasUnfinishedContractChange(data)){
  1371 + throw new DefaultClientException("合同变更中,无法锁价!");
  1372 + }
  1373 +
1295 List<UpdateContractDistributorLineVo> lineVoList = vo.getContractDistributorLineList(); 1374 List<UpdateContractDistributorLineVo> lineVoList = vo.getContractDistributorLineList();
1296 if (CollectionUtils.isEmpty(lineVoList)) { 1375 if (CollectionUtils.isEmpty(lineVoList)) {
1297 throw new DefaultClientException("合同行数据为空!"); 1376 throw new DefaultClientException("合同行数据为空!");
@@ -1305,6 +1384,7 @@ public class ContractDistributorStandardServiceImpl extends @@ -1305,6 +1384,7 @@ public class ContractDistributorStandardServiceImpl extends
1305 data.setOrderDate(LocalDate.now()); 1384 data.setOrderDate(LocalDate.now());
1306 data.setStatus("STANDARD"); 1385 data.setStatus("STANDARD");
1307 data.setParentId(vo.getId()); 1386 data.setParentId(vo.getId());
  1387 + data.setPriceLockUserId(SecurityUtil.getCurrentUser().getId());
1308 data.setChangeReason(vo.getChangeReason()); 1388 data.setChangeReason(vo.getChangeReason());
1309 // data.setStandardizedAt(LocalDateTime.now()); 1389 // data.setStandardizedAt(LocalDateTime.now());
1310 getBaseMapper().insert(data); 1390 getBaseMapper().insert(data);
@@ -1419,6 +1499,10 @@ public class ContractDistributorStandardServiceImpl extends @@ -1419,6 +1499,10 @@ public class ContractDistributorStandardServiceImpl extends
1419 throw new DefaultClientException("合同不存在!"); 1499 throw new DefaultClientException("合同不存在!");
1420 } 1500 }
1421 1501
  1502 + if(hasUnfinishedContractChange(data)){
  1503 + throw new DefaultClientException("合同变更中,无法锁规!");
  1504 + }
  1505 +
1422 List<UpdateContractDistributorLineVo> lineVoList = vo.getContractDistributorLineList(); 1506 List<UpdateContractDistributorLineVo> lineVoList = vo.getContractDistributorLineList();
1423 if (CollectionUtils.isEmpty(lineVoList)) { 1507 if (CollectionUtils.isEmpty(lineVoList)) {
1424 throw new DefaultClientException("合同行数据为空!"); 1508 throw new DefaultClientException("合同行数据为空!");
@@ -1506,6 +1590,20 @@ public class ContractDistributorStandardServiceImpl extends @@ -1506,6 +1590,20 @@ public class ContractDistributorStandardServiceImpl extends
1506 // createPurchaseOrderInfo(data, "PRODUCTION"); 1590 // createPurchaseOrderInfo(data, "PRODUCTION");
1507 } 1591 }
1508 1592
  1593 + /**
  1594 + * 是否存在未结束的合同变更
  1595 + *
  1596 + * @param data 合同
  1597 + * @return 是否存在未结束的合同变更
  1598 + */
  1599 + private boolean hasUnfinishedContractChange(ContractDistributorStandard data) {
  1600 + if (data == null) {
  1601 + return false;
  1602 + }
  1603 + String rootContractId = StringUtils.isBlank(data.getParentId()) ? data.getId() : data.getParentId();
  1604 + return contractChangeApplicationService.hasUnfinishedApplication(rootContractId);
  1605 + }
  1606 +
1509 private String buildSpecificationLockContractCode(String contractCode, String contractType, int lockBatchNo) { 1607 private String buildSpecificationLockContractCode(String contractCode, String contractType, int lockBatchNo) {
1510 if (!isOpenSpecContract(contractType) || StringUtils.isBlank(contractCode)) { 1608 if (!isOpenSpecContract(contractType) || StringUtils.isBlank(contractCode)) {
1511 return contractCode; 1609 return contractCode;
@@ -409,6 +409,7 @@ public class OrderChangeRecordServiceImpl extends BaseMpServiceImpl<OrderChangeR @@ -409,6 +409,7 @@ public class OrderChangeRecordServiceImpl extends BaseMpServiceImpl<OrderChangeR
409 List<PurchaseOrderLine> afterChangeSpecList = record.getAfterChangeSpecList(); 409 List<PurchaseOrderLine> afterChangeSpecList = record.getAfterChangeSpecList();
410 if (CollectionUtils.isNotEmpty(afterChangeSpecList)) { 410 if (CollectionUtils.isNotEmpty(afterChangeSpecList)) {
411 orderInfo.setStockUpCompanyName(purchaseOrderInfo.getStockUpCompanyName()); 411 orderInfo.setStockUpCompanyName(purchaseOrderInfo.getStockUpCompanyName());
  412 + orderInfo.setType(purchaseOrderInfo.getType());
412 for (PurchaseOrderLine line : afterChangeSpecList) { 413 for (PurchaseOrderLine line : afterChangeSpecList) {
413 createOrderDetailReport(line, orderDetailReport, orderInfo, standard, null 414 createOrderDetailReport(line, orderDetailReport, orderInfo, standard, null
414 , purchaseOrderInfo.getContractCreateById()); 415 , purchaseOrderInfo.getContractCreateById());
@@ -514,6 +515,7 @@ public class OrderChangeRecordServiceImpl extends BaseMpServiceImpl<OrderChangeR @@ -514,6 +515,7 @@ public class OrderChangeRecordServiceImpl extends BaseMpServiceImpl<OrderChangeR
514 PurchaseOrderInfo orderInfo, ContractDistributorStandard standard, String type1, 515 PurchaseOrderInfo orderInfo, ContractDistributorStandard standard, String type1,
515 String contractCreateById) { 516 String contractCreateById) {
516 CreateOrderDetailReportVo vo = new CreateOrderDetailReportVo(); 517 CreateOrderDetailReportVo vo = new CreateOrderDetailReportVo();
  518 + vo.setOrderingUnitName(orderDetailReport.getOrderingUnitName());
517 if ("offset".equals(type1)) { 519 if ("offset".equals(type1)) {
518 vo.setPurchaseOrderLineId(line.getId()); 520 vo.setPurchaseOrderLineId(line.getId());
519 vo.setQuantity(line.getQuantity().negate()); 521 vo.setQuantity(line.getQuantity().negate());
@@ -524,13 +526,13 @@ public class OrderChangeRecordServiceImpl extends BaseMpServiceImpl<OrderChangeR @@ -524,13 +526,13 @@ public class OrderChangeRecordServiceImpl extends BaseMpServiceImpl<OrderChangeR
524 vo.setPurchaseOrderLineId(line.getId()); 526 vo.setPurchaseOrderLineId(line.getId());
525 } 527 }
526 vo.setQuantity(line.getQuantity()); 528 vo.setQuantity(line.getQuantity());
  529 + vo.setOrderingUnitName(orderInfo.getOrderingUnitName());
527 } 530 }
528 vo.setOrderNo(orderDetailReport.getOrderNo()); 531 vo.setOrderNo(orderDetailReport.getOrderNo());
529 vo.setOrderDate(orderDetailReport.getOrderDate()); 532 vo.setOrderDate(orderDetailReport.getOrderDate());
530 vo.setWorkshopId(orderDetailReport.getWorkshopId()); 533 vo.setWorkshopId(orderDetailReport.getWorkshopId());
531 vo.setDeptName(orderDetailReport.getDeptName()); 534 vo.setDeptName(orderDetailReport.getDeptName());
532 vo.setRegionName(orderDetailReport.getRegionName()); 535 vo.setRegionName(orderDetailReport.getRegionName());
533 - vo.setOrderingUnitName(orderDetailReport.getOrderingUnitName());  
534 vo.setIndustry(line.getIndustry()); 536 vo.setIndustry(line.getIndustry());
535 vo.setBrand(line.getBrand()); 537 vo.setBrand(line.getBrand());
536 vo.setThickness(line.getThickness()); 538 vo.setThickness(line.getThickness());
  1 +package com.lframework.xingyun.sc.mappers;
  2 +
  3 +import com.lframework.starter.web.core.annotations.permission.DataPermission;
  4 +import com.lframework.starter.web.core.annotations.permission.DataPermissions;
  5 +import com.lframework.starter.web.core.mapper.BaseMapper;
  6 +import com.lframework.starter.web.inner.components.permission.OrderDataPermissionDataPermissionType;
  7 +import com.lframework.xingyun.sc.entity.ContractChangeApplication;
  8 +import com.lframework.xingyun.sc.entity.ContractDistributorStandard;
  9 +import com.lframework.xingyun.sc.vo.contract.queryVo.QueryContractChangeSelectableContractVo;
  10 +import org.apache.ibatis.annotations.Param;
  11 +
  12 +import java.util.List;
  13 +
  14 +/**
  15 + * <p>
  16 + * 合同变更申请单 Mapper 接口
  17 + * </p>
  18 + */
  19 +public interface ContractChangeApplicationMapper extends BaseMapper<ContractChangeApplication> {
  20 +
  21 + /**
  22 + * 查询可发起变更的合同
  23 + *
  24 + * @param vo 查询参数
  25 + * @return 可发起变更的合同
  26 + */
  27 + @DataPermissions(type = OrderDataPermissionDataPermissionType.class, value = {
  28 + @DataPermission(template = "order", alias = "tb")
  29 + })
  30 + List<ContractDistributorStandard> querySelectableContracts(@Param("vo") QueryContractChangeSelectableContractVo vo);
  31 +}
  1 +package com.lframework.xingyun.sc.service.contract;
  2 +
  3 +import com.lframework.starter.web.core.components.resp.PageResult;
  4 +import com.lframework.starter.web.core.service.BaseMpService;
  5 +import com.lframework.xingyun.sc.entity.ContractChangeApplication;
  6 +import com.lframework.xingyun.sc.entity.ContractDistributorStandard;
  7 +import com.lframework.xingyun.sc.vo.contract.createVo.CreateContractChangeApplicationVo;
  8 +import com.lframework.xingyun.sc.vo.contract.queryVo.QueryContractChangeApplicationVo;
  9 +import com.lframework.xingyun.sc.vo.contract.queryVo.QueryContractChangeSelectableContractVo;
  10 +import com.lframework.xingyun.sc.vo.contract.updateVo.UpdateContractChangeApplicationVo;
  11 +
  12 +/**
  13 + * 合同变更申请单 Service
  14 + */
  15 +public interface ContractChangeApplicationService extends BaseMpService<ContractChangeApplication> {
  16 +
  17 + /**
  18 + * 查询列表
  19 + *
  20 + * @param pageIndex 页码
  21 + * @param pageSize 页大小
  22 + * @param vo 查询参数
  23 + * @return 分页结果
  24 + */
  25 + PageResult<ContractChangeApplication> query(Integer pageIndex, Integer pageSize, QueryContractChangeApplicationVo vo);
  26 +
  27 + /**
  28 + * 根据ID查询
  29 + *
  30 + * @param id ID
  31 + * @return 合同变更申请单
  32 + */
  33 + ContractChangeApplication findById(String id);
  34 +
  35 + /**
  36 + * 创建
  37 + *
  38 + * @param vo 新增参数
  39 + * @return ID
  40 + * @throws Exception 异常
  41 + */
  42 + String create(CreateContractChangeApplicationVo vo) throws Exception;
  43 +
  44 + /**
  45 + * 修改
  46 + *
  47 + * @param vo 修改参数
  48 + * @throws Exception 异常
  49 + */
  50 + void update(UpdateContractChangeApplicationVo vo) throws Exception;
  51 +
  52 + /**
  53 + * 取消申请
  54 + *
  55 + * @param id ID
  56 + */
  57 + void cancelApplication(String id);
  58 +
  59 + /**
  60 + * 更新审核状态
  61 + *
  62 + * @param id ID
  63 + * @param approvalStatus 审核状态
  64 + */
  65 + void updateAuditStatus(String id, String approvalStatus);
  66 +
  67 + /**
  68 + * 查询可发起变更的合同
  69 + *
  70 + * @param pageIndex 页码
  71 + * @param pageSize 页大小
  72 + * @param vo 查询参数
  73 + * @return 分页结果
  74 + */
  75 + PageResult<ContractDistributorStandard> querySelectableContracts(Integer pageIndex, Integer pageSize,
  76 + QueryContractChangeSelectableContractVo vo);
  77 +
  78 + /**
  79 + * 是否存在未结束的合同变更申请单
  80 + *
  81 + * @param rootContractId 根合同ID
  82 + * @return 是否存在未结束的合同变更申请单
  83 + */
  84 + boolean hasUnfinishedApplication(String rootContractId);
  85 +}
  1 +package com.lframework.xingyun.sc.vo.contract.createVo;
  2 +
  3 +import com.lframework.starter.web.core.vo.BaseVo;
  4 +import com.lframework.xingyun.sc.vo.contract.updateVo.UpdateContractDistributorStandardVo;
  5 +import io.swagger.annotations.ApiModelProperty;
  6 +import lombok.Data;
  7 +import org.hibernate.validator.constraints.Length;
  8 +
  9 +import javax.validation.Valid;
  10 +import javax.validation.constraints.NotBlank;
  11 +import javax.validation.constraints.NotNull;
  12 +import java.io.Serializable;
  13 +
  14 +/**
  15 + * 合同变更申请单新增参数
  16 + */
  17 +@Data
  18 +public class CreateContractChangeApplicationVo implements BaseVo, Serializable {
  19 +
  20 + private static final long serialVersionUID = 1L;
  21 +
  22 + /**
  23 + * 合同ID
  24 + */
  25 + @ApiModelProperty(value = "合同ID", required = true)
  26 + @NotBlank(message = "合同ID不能为空!")
  27 + private String contractId;
  28 +
  29 + /**
  30 + * 变更原因
  31 + */
  32 + @ApiModelProperty(value = "变更原因")
  33 + @Length(message = "变更原因最多允许500个字符!")
  34 + private String changeReason;
  35 +
  36 + /**
  37 + * 变更后的合同数据
  38 + */
  39 + @ApiModelProperty(value = "变更后的合同数据", required = true)
  40 + @NotNull(message = "变更后的合同数据不能为空!")
  41 + @Valid
  42 + private UpdateContractDistributorStandardVo contractData;
  43 +}
  1 +package com.lframework.xingyun.sc.vo.contract.queryVo;
  2 +
  3 +import com.lframework.starter.web.core.vo.BaseVo;
  4 +import com.lframework.starter.web.core.vo.PageVo;
  5 +import io.swagger.annotations.ApiModelProperty;
  6 +import lombok.Data;
  7 +
  8 +import java.io.Serializable;
  9 +
  10 +/**
  11 + * 合同变更申请单查询参数
  12 + */
  13 +@Data
  14 +public class QueryContractChangeApplicationVo extends PageVo implements BaseVo, Serializable {
  15 +
  16 + private static final long serialVersionUID = 1L;
  17 +
  18 + /**
  19 + * 合同编号
  20 + */
  21 + @ApiModelProperty("合同编号")
  22 + private String contractCode;
  23 +
  24 + /**
  25 + * 合同类型
  26 + */
  27 + @ApiModelProperty("合同类型")
  28 + private String contractType;
  29 +
  30 + /**
  31 + * 合同阶段(FORMAL:正式合同,STANDARD:标准合同)
  32 + */
  33 + @ApiModelProperty("合同阶段(FORMAL:正式合同,STANDARD:标准合同)")
  34 + private String contractStage;
  35 +
  36 + /**
  37 + * 审核状态
  38 + */
  39 + @ApiModelProperty("审核状态")
  40 + private String approvalStatus;
  41 +
  42 + /**
  43 + * 需方名称
  44 + */
  45 + @ApiModelProperty("需方名称")
  46 + private String buyerName;
  47 +}
  1 +package com.lframework.xingyun.sc.vo.contract.queryVo;
  2 +
  3 +import com.lframework.starter.web.core.vo.BaseVo;
  4 +import com.lframework.starter.web.core.vo.PageVo;
  5 +import io.swagger.annotations.ApiModelProperty;
  6 +import lombok.Data;
  7 +
  8 +import java.io.Serializable;
  9 +
  10 +/**
  11 + * 可发起合同变更合同查询参数
  12 + */
  13 +@Data
  14 +public class QueryContractChangeSelectableContractVo extends PageVo implements BaseVo, Serializable {
  15 +
  16 + private static final long serialVersionUID = 1L;
  17 +
  18 + /**
  19 + * 合同编号
  20 + */
  21 + @ApiModelProperty("合同编号")
  22 + private String code;
  23 +
  24 + /**
  25 + * 合同类型
  26 + */
  27 + @ApiModelProperty("合同类型")
  28 + private String type;
  29 +
  30 + /**
  31 + * 合同阶段(FORMAL:正式合同,STANDARD:标准合同)
  32 + */
  33 + @ApiModelProperty("合同阶段(FORMAL:正式合同,STANDARD:标准合同)")
  34 + private String contractStage;
  35 +}
  1 +package com.lframework.xingyun.sc.vo.contract.updateVo;
  2 +
  3 +import com.lframework.starter.web.core.vo.BaseVo;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +import org.hibernate.validator.constraints.Length;
  7 +
  8 +import javax.validation.Valid;
  9 +import javax.validation.constraints.NotBlank;
  10 +import javax.validation.constraints.NotNull;
  11 +import java.io.Serializable;
  12 +
  13 +/**
  14 + * 合同变更申请单修改参数
  15 + */
  16 +@Data
  17 +public class UpdateContractChangeApplicationVo implements BaseVo, Serializable {
  18 +
  19 + private static final long serialVersionUID = 1L;
  20 +
  21 + /**
  22 + * ID
  23 + */
  24 + @ApiModelProperty(value = "ID", required = true)
  25 + @NotBlank(message = "ID不能为空!")
  26 + private String id;
  27 +
  28 + /**
  29 + * 变更原因
  30 + */
  31 + @ApiModelProperty(value = "变更原因")
  32 + @Length(message = "变更原因最多允许500个字符!")
  33 + private String changeReason;
  34 +
  35 + /**
  36 + * 变更后的合同数据
  37 + */
  38 + @ApiModelProperty(value = "变更后的合同数据", required = true)
  39 + @NotNull(message = "变更后的合同数据不能为空!")
  40 + @Valid
  41 + private UpdateContractDistributorStandardVo contractData;
  42 +}
@@ -168,4 +168,11 @@ public class QueryPurchaseOrderInfoVo extends PageVo implements BaseVo, Serializ @@ -168,4 +168,11 @@ public class QueryPurchaseOrderInfoVo extends PageVo implements BaseVo, Serializ
168 */ 168 */
169 @ApiModelProperty("导出类型") 169 @ApiModelProperty("导出类型")
170 private String templateType; 170 private String templateType;
  171 +
  172 + /**
  173 + * 操作时间
  174 + */
  175 + @ApiModelProperty("操作时间")
  176 + private String createTimeStart;
  177 + private String createTimeEnd;
171 } 178 }
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3 +<mapper namespace="com.lframework.xingyun.sc.mappers.ContractChangeApplicationMapper">
  4 +
  5 + <select id="querySelectableContracts" resultType="com.lframework.xingyun.sc.entity.ContractDistributorStandard">
  6 + SELECT tb.id,
  7 + tb.code,
  8 + tb.buyer,
  9 + tb.dept_id,
  10 + tb.region,
  11 + tb.stock_up_company_id,
  12 + tb.order_date,
  13 + tb.unit,
  14 + tb.workshop_id,
  15 + tb.total_quantity,
  16 + tb.total_amount_including_tax,
  17 + tb.status,
  18 + tb.type,
  19 + tb.parent_id,
  20 + tb.formal_approved,
  21 + tb.standard_approved,
  22 + tb.price_spec_locked,
  23 + tb.change_reason,
  24 + tb.create_by,
  25 + tb.create_by_id,
  26 + tb.create_time
  27 + FROM tbl_contract_distributor_standard tb
  28 + WHERE tb.status != 'DELETED'
  29 + <if test="vo.code != null and vo.code != ''">
  30 + AND tb.code LIKE CONCAT('%', #{vo.code}, '%')
  31 + </if>
  32 + <if test="vo.type != null and vo.type != ''">
  33 + AND tb.type = #{vo.type}
  34 + </if>
  35 + <if test="vo.contractStage != null and vo.contractStage != ''">
  36 + AND tb.status = #{vo.contractStage}
  37 + </if>
  38 + AND (
  39 + (tb.type = 'DISTRIB_STD' AND tb.status = 'STANDARD' AND tb.standard_approved = 'PASS')
  40 + OR (tb.type = 'DIST_STOCK_CONTRACT' AND (
  41 + (tb.status = 'FORMAL' AND tb.formal_approved = 'PASS')
  42 + OR (tb.status = 'STANDARD' AND tb.standard_approved = 'PASS')
  43 + ))
  44 + OR (tb.type = 'DRAFT_DIST_AGMT' AND tb.status = 'STANDARD' AND tb.standard_approved = 'PASS')
  45 + OR (tb.type = 'INTL_STD_CONTRACT' AND tb.status = 'STANDARD' AND tb.standard_approved = 'PASS')
  46 + OR (tb.type = 'INTL_INVENTORY_AGMT' AND (
  47 + (tb.status = 'FORMAL' AND tb.formal_approved = 'PASS')
  48 + OR (tb.status = 'STANDARD' AND tb.standard_approved = 'PASS')
  49 + ))
  50 + OR (tb.type = 'INTL_OPEN_SPEC_AGMT' AND tb.status = 'STANDARD' AND tb.standard_approved = 'PASS')
  51 + OR (tb.type = 'PROCESS_STD_AGMT' AND tb.status = 'STANDARD' AND tb.standard_approved = 'PASS')
  52 + )
  53 + AND NOT EXISTS (
  54 + SELECT 1
  55 + FROM tbl_contract_change_application cca
  56 + WHERE cca.root_contract_id = IFNULL(NULLIF(tb.parent_id, ''), tb.id)
  57 + AND cca.approval_status NOT IN ('PASS', 'CANCEL')
  58 + )
  59 + ORDER BY tb.create_time DESC
  60 + </select>
  61 +</mapper>
@@ -65,6 +65,8 @@ @@ -65,6 +65,8 @@
65 <result column="standardized_at" property="standardizedAt"/> 65 <result column="standardized_at" property="standardizedAt"/>
66 <result column="title" property="title"/> 66 <result column="title" property="title"/>
67 <result column="change_reason" property="changeReason"/> 67 <result column="change_reason" property="changeReason"/>
  68 + <result column="price_lock_user_id" property="priceLockUserId"/>
  69 + <result column="changed" property="changed"/>
68 </resultMap> 70 </resultMap>
69 71
70 <sql id="ContractDistributorStandard_sql"> 72 <sql id="ContractDistributorStandard_sql">
@@ -129,7 +131,9 @@ @@ -129,7 +131,9 @@
129 tb.formalized_at, 131 tb.formalized_at,
130 tb.standardized_at, 132 tb.standardized_at,
131 tb.title, 133 tb.title,
132 - tb.change_reason 134 + tb.change_reason,
  135 + tb.price_lock_user_id,
  136 + tb.changed
133 FROM tbl_contract_distributor_standard AS tb 137 FROM tbl_contract_distributor_standard AS tb
134 </sql> 138 </sql>
135 139
@@ -204,6 +204,14 @@ @@ -204,6 +204,14 @@
204 #{id} 204 #{id}
205 </foreach> 205 </foreach>
206 </if> 206 </if>
  207 + <if test="vo.createTimeStart != null">
  208 + AND tb.create_time >= #{vo.createTimeStart}
  209 + </if>
  210 + <if test="vo.createTimeEnd != null">
  211 + <![CDATA[
  212 + AND tb.create_time < DATE_ADD(#{vo.createTimeEnd}, INTERVAL 1 DAY)
  213 + ]]>
  214 + </if>
207 </where> 215 </where>
208 ORDER BY tb.create_time DESC 216 ORDER BY tb.create_time DESC
209 </select> 217 </select>