Showing
11 changed files
with
609 additions
and
2 deletions
| ... | ... | @@ -1803,3 +1803,28 @@ CREATE TABLE `procurement_supplier_quotation_project` |
| 1803 | 1803 | KEY `idx_psqpj_bid_time` (`bid_time`), |
| 1804 | 1804 | KEY `idx_psqpj_create_time` (`create_time`) |
| 1805 | 1805 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='供应商报价项目'; |
| 1806 | + | |
| 1807 | +CREATE TABLE `procurement_supplier_quotation_project_quote` | |
| 1808 | +( | |
| 1809 | + `id` varchar(32) NOT NULL COMMENT 'ID', | |
| 1810 | + `project_id` varchar(32) NOT NULL COMMENT '报价项目ID', | |
| 1811 | + `supplier_id` varchar(32) NOT NULL COMMENT '供应商ID(当前登录用户ID)', | |
| 1812 | + `supplier_name` varchar(200) NOT NULL COMMENT '供应商名称', | |
| 1813 | + `quote_time` datetime NOT NULL COMMENT '报价时间(最后一次报价时间)', | |
| 1814 | + `product_id` varchar(32) NOT NULL COMMENT '品种ID', | |
| 1815 | + `quantity` decimal(18, 5) NOT NULL COMMENT '数量', | |
| 1816 | + `price` decimal(18, 10) NOT NULL COMMENT '价格', | |
| 1817 | + `bid_status` varchar(50) DEFAULT NULL COMMENT '中标状态(中标/未中标/废标)', | |
| 1818 | + `create_by_id` varchar(32) DEFAULT NULL COMMENT '创建人ID', | |
| 1819 | + `create_by` varchar(64) DEFAULT NULL COMMENT '创建人', | |
| 1820 | + `update_by_id` varchar(32) DEFAULT NULL COMMENT '更新人ID', | |
| 1821 | + `update_by` varchar(64) DEFAULT NULL COMMENT '更新人', | |
| 1822 | + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', | |
| 1823 | + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', | |
| 1824 | + PRIMARY KEY (`id`), | |
| 1825 | + UNIQUE KEY `uk_psqpjq_project_supplier` (`project_id`, `supplier_id`), | |
| 1826 | + KEY `idx_psqpjq_project_id` (`project_id`), | |
| 1827 | + KEY `idx_psqpjq_supplier_id` (`supplier_id`), | |
| 1828 | + KEY `idx_psqpjq_quote_time` (`quote_time`), | |
| 1829 | + KEY `idx_psqpjq_create_time` (`create_time`) | |
| 1830 | +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='供应商报价项目报价'; | ... | ... |
| 1 | +package com.lframework.xingyun.sc.procurement.controller.quotation; | |
| 2 | + | |
| 3 | +import com.lframework.starter.web.core.components.resp.InvokeResult; | |
| 4 | +import com.lframework.starter.web.core.components.resp.InvokeResultBuilder; | |
| 5 | +import com.lframework.starter.web.core.controller.DefaultBaseController; | |
| 6 | +import com.lframework.xingyun.sc.procurement.entity.SupplierQuotationProjectQuote; | |
| 7 | +import com.lframework.xingyun.sc.procurement.service.quotation.SupplierQuotationProjectQuoteService; | |
| 8 | +import com.lframework.xingyun.sc.procurement.vo.quotation.SupplierQuotationProjectQuoteVo; | |
| 9 | +import com.lframework.xingyun.sc.procurement.vo.quotation.UpdateSupplierQuotationProjectQuoteBidStatusVo; | |
| 10 | +import io.swagger.annotations.Api; | |
| 11 | +import io.swagger.annotations.ApiImplicitParam; | |
| 12 | +import io.swagger.annotations.ApiOperation; | |
| 13 | +import java.util.List; | |
| 14 | +import javax.annotation.Resource; | |
| 15 | +import javax.validation.Valid; | |
| 16 | +import javax.validation.constraints.NotBlank; | |
| 17 | +import org.springframework.validation.annotation.Validated; | |
| 18 | +import org.springframework.web.bind.annotation.GetMapping; | |
| 19 | +import org.springframework.web.bind.annotation.PostMapping; | |
| 20 | +import org.springframework.web.bind.annotation.PutMapping; | |
| 21 | +import org.springframework.web.bind.annotation.RequestBody; | |
| 22 | +import org.springframework.web.bind.annotation.RequestMapping; | |
| 23 | +import org.springframework.web.bind.annotation.RestController; | |
| 24 | + | |
| 25 | +@Api(tags = "供应商报价项目报价") | |
| 26 | +@Validated | |
| 27 | +@RestController | |
| 28 | +@RequestMapping("/procurement/supplierQuotationProjectQuote") | |
| 29 | +public class SupplierQuotationProjectQuoteController extends DefaultBaseController { | |
| 30 | + | |
| 31 | + @Resource | |
| 32 | + private SupplierQuotationProjectQuoteService supplierQuotationProjectQuoteService; | |
| 33 | + | |
| 34 | + @ApiOperation("供应商报价(同一项目可多次报价,覆盖更新)") | |
| 35 | + @PostMapping("") | |
| 36 | + public InvokeResult<Void> quote(@Valid @RequestBody SupplierQuotationProjectQuoteVo vo) { | |
| 37 | + supplierQuotationProjectQuoteService.quote(vo); | |
| 38 | + return InvokeResultBuilder.success(); | |
| 39 | + } | |
| 40 | + | |
| 41 | + @ApiOperation("查看我的报价(每项目仅一条)") | |
| 42 | + @ApiImplicitParam(value = "projectId", name = "projectId", paramType = "query", required = true) | |
| 43 | + @GetMapping("/my") | |
| 44 | + public InvokeResult<SupplierQuotationProjectQuote> getMyQuote(@NotBlank(message = "projectId不能为空!") String projectId) { | |
| 45 | + return InvokeResultBuilder.success(supplierQuotationProjectQuoteService.getMyQuote(projectId)); | |
| 46 | + } | |
| 47 | + | |
| 48 | + @ApiOperation("查看项目供应商报价(发布方/管理方使用)") | |
| 49 | + @ApiImplicitParam(value = "projectId", name = "projectId", paramType = "query", required = true) | |
| 50 | + @GetMapping("/listByProject") | |
| 51 | + public InvokeResult<List<SupplierQuotationProjectQuote>> listByProject(@NotBlank(message = "projectId不能为空!") String projectId) { | |
| 52 | + return InvokeResultBuilder.success(supplierQuotationProjectQuoteService.listByProject(projectId)); | |
| 53 | + } | |
| 54 | + | |
| 55 | + @ApiOperation("维护中标状态(发布方/管理方使用)") | |
| 56 | + @PutMapping("/bidStatus") | |
| 57 | + public InvokeResult<Void> updateBidStatus(@Valid @RequestBody UpdateSupplierQuotationProjectQuoteBidStatusVo vo) { | |
| 58 | + supplierQuotationProjectQuoteService.updateBidStatus(vo); | |
| 59 | + return InvokeResultBuilder.success(); | |
| 60 | + } | |
| 61 | +} | |
| 62 | + | ... | ... |
| ... | ... | @@ -7,6 +7,8 @@ import com.lframework.starter.web.core.dto.BaseDto; |
| 7 | 7 | import com.lframework.starter.web.core.entity.BaseEntity; |
| 8 | 8 | import java.math.BigDecimal; |
| 9 | 9 | import java.time.LocalDateTime; |
| 10 | +import java.util.List; | |
| 11 | + | |
| 10 | 12 | import lombok.Data; |
| 11 | 13 | |
| 12 | 14 | @Data |
| ... | ... | @@ -85,6 +87,12 @@ public class SupplierQuotationProject extends BaseEntity implements BaseDto { |
| 85 | 87 | private String status; |
| 86 | 88 | |
| 87 | 89 | /** |
| 90 | + * 供应商报价 | |
| 91 | + */ | |
| 92 | + @TableField(exist = false) | |
| 93 | + private List<SupplierQuotationProjectQuote> supplierQuotationProjectQuoteList; | |
| 94 | + | |
| 95 | + /** | |
| 88 | 96 | * 创建人ID |
| 89 | 97 | */ |
| 90 | 98 | @TableField(fill = FieldFill.INSERT) | ... | ... |
| 1 | +package com.lframework.xingyun.sc.procurement.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 java.math.BigDecimal; | |
| 9 | +import java.time.LocalDateTime; | |
| 10 | +import lombok.Data; | |
| 11 | + | |
| 12 | +@Data | |
| 13 | +@TableName("procurement_supplier_quotation_project_quote") | |
| 14 | +public class SupplierQuotationProjectQuote extends BaseEntity implements BaseDto { | |
| 15 | + | |
| 16 | + private static final long serialVersionUID = 1L; | |
| 17 | + | |
| 18 | + public static final String CACHE_NAME = "SupplierQuotationProjectQuote"; | |
| 19 | + | |
| 20 | + /** | |
| 21 | + * ID | |
| 22 | + */ | |
| 23 | + private String id; | |
| 24 | + | |
| 25 | + /** | |
| 26 | + * 报价项目ID | |
| 27 | + */ | |
| 28 | + private String projectId; | |
| 29 | + | |
| 30 | + /** | |
| 31 | + * 供应商ID(当前登录用户ID) | |
| 32 | + */ | |
| 33 | + private String supplierId; | |
| 34 | + | |
| 35 | + /** | |
| 36 | + * 供应商名称 | |
| 37 | + */ | |
| 38 | + private String supplierName; | |
| 39 | + | |
| 40 | + /** | |
| 41 | + * 报价时间(最后一次报价时间) | |
| 42 | + */ | |
| 43 | + private LocalDateTime quoteTime; | |
| 44 | + | |
| 45 | + /** | |
| 46 | + * 品种ID | |
| 47 | + */ | |
| 48 | + private String productId; | |
| 49 | + | |
| 50 | + /** | |
| 51 | + * 品种名称 | |
| 52 | + */ | |
| 53 | + @TableField(exist = false) | |
| 54 | + private String productName; | |
| 55 | + | |
| 56 | + /** | |
| 57 | + * 品种代号 | |
| 58 | + */ | |
| 59 | + @TableField(exist = false) | |
| 60 | + private String productCode; | |
| 61 | + | |
| 62 | + /** | |
| 63 | + * 数量 | |
| 64 | + */ | |
| 65 | + private BigDecimal quantity; | |
| 66 | + | |
| 67 | + /** | |
| 68 | + * 价格 | |
| 69 | + */ | |
| 70 | + private BigDecimal price; | |
| 71 | + | |
| 72 | + /** | |
| 73 | + * 中标状态(中标/未中标/废标) | |
| 74 | + */ | |
| 75 | + private String bidStatus; | |
| 76 | + | |
| 77 | + /** | |
| 78 | + * 创建人ID | |
| 79 | + */ | |
| 80 | + @TableField(fill = FieldFill.INSERT) | |
| 81 | + private String createById; | |
| 82 | + | |
| 83 | + /** | |
| 84 | + * 创建人 | |
| 85 | + */ | |
| 86 | + @TableField(fill = FieldFill.INSERT) | |
| 87 | + private String createBy; | |
| 88 | + | |
| 89 | + /** | |
| 90 | + * 更新人ID | |
| 91 | + */ | |
| 92 | + @TableField(fill = FieldFill.INSERT_UPDATE) | |
| 93 | + private String updateById; | |
| 94 | + | |
| 95 | + /** | |
| 96 | + * 更新人 | |
| 97 | + */ | |
| 98 | + @TableField(fill = FieldFill.INSERT_UPDATE) | |
| 99 | + private String updateBy; | |
| 100 | + | |
| 101 | + /** | |
| 102 | + * 创建时间 | |
| 103 | + */ | |
| 104 | + @TableField(fill = FieldFill.INSERT) | |
| 105 | + private LocalDateTime createTime; | |
| 106 | + | |
| 107 | + /** | |
| 108 | + * 更新时间 | |
| 109 | + */ | |
| 110 | + @TableField(fill = FieldFill.INSERT_UPDATE) | |
| 111 | + private LocalDateTime updateTime; | |
| 112 | +} | |
| 113 | + | ... | ... |
| 1 | +package com.lframework.xingyun.sc.procurement.impl.quotation; | |
| 2 | + | |
| 3 | +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | |
| 4 | +import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |
| 5 | +import com.lframework.starter.common.exceptions.impl.DefaultClientException; | |
| 6 | +import com.lframework.starter.common.utils.CollectionUtil; | |
| 7 | +import com.lframework.starter.common.utils.ObjectUtil; | |
| 8 | +import com.lframework.starter.web.core.annotations.oplog.OpLog; | |
| 9 | +import com.lframework.starter.web.core.impl.BaseMpServiceImpl; | |
| 10 | +import com.lframework.starter.web.core.utils.IdUtil; | |
| 11 | +import com.lframework.starter.web.core.utils.OpLogUtil; | |
| 12 | +import com.lframework.starter.web.core.components.security.SecurityUtil; | |
| 13 | +import com.lframework.starter.web.inner.components.oplog.OtherOpLogType; | |
| 14 | +import com.lframework.starter.web.inner.entity.SysRole; | |
| 15 | +import com.lframework.starter.web.inner.entity.SysUser; | |
| 16 | +import com.lframework.starter.web.inner.service.system.SysRoleService; | |
| 17 | +import com.lframework.starter.web.inner.service.system.SysUserService; | |
| 18 | +import com.lframework.xingyun.basedata.entity.BreedRelationship; | |
| 19 | +import com.lframework.xingyun.basedata.service.breed.BreedRelationshipService; | |
| 20 | +import com.lframework.xingyun.sc.procurement.entity.SupplierQuotationProject; | |
| 21 | +import com.lframework.xingyun.sc.procurement.entity.SupplierQuotationProjectQuote; | |
| 22 | +import com.lframework.xingyun.sc.procurement.mappers.quotation.SupplierQuotationProjectMapper; | |
| 23 | +import com.lframework.xingyun.sc.procurement.mappers.quotation.SupplierQuotationProjectQuoteMapper; | |
| 24 | +import com.lframework.xingyun.sc.procurement.service.quotation.SupplierQuotationProjectQuoteService; | |
| 25 | +import com.lframework.xingyun.sc.procurement.vo.quotation.SupplierQuotationProjectQuoteVo; | |
| 26 | +import com.lframework.xingyun.sc.procurement.vo.quotation.UpdateSupplierQuotationProjectQuoteBidStatusVo; | |
| 27 | +import java.io.Serializable; | |
| 28 | +import java.time.LocalDateTime; | |
| 29 | +import java.util.Collections; | |
| 30 | +import java.util.List; | |
| 31 | +import java.util.Set; | |
| 32 | +import java.util.stream.Collectors; | |
| 33 | +import javax.annotation.Resource; | |
| 34 | +import org.apache.commons.lang3.StringUtils; | |
| 35 | +import org.springframework.stereotype.Service; | |
| 36 | +import org.springframework.transaction.annotation.Transactional; | |
| 37 | + | |
| 38 | +@Service | |
| 39 | +public class SupplierQuotationProjectQuoteServiceImpl | |
| 40 | + extends BaseMpServiceImpl<SupplierQuotationProjectQuoteMapper, SupplierQuotationProjectQuote> | |
| 41 | + implements SupplierQuotationProjectQuoteService { | |
| 42 | + | |
| 43 | + private static final String BID_STATUS_WIN = "中标"; | |
| 44 | + private static final String BID_STATUS_LOSE = "未中标"; | |
| 45 | + private static final String BID_STATUS_ABORT = "废标"; | |
| 46 | + | |
| 47 | + private static final String PROJECT_STATUS_COMPLETED = "COMPLETED"; | |
| 48 | + private static final String PROJECT_STATUS_ABORTED = "ABORTED"; | |
| 49 | + | |
| 50 | + private static final String PROJECT_TYPE_CENTRAL_BID = "CENTRAL_BID"; | |
| 51 | + private static final String PROJECT_TYPE_CENTRAL_BID_CN = "集中开标"; | |
| 52 | + private static final String PROJECT_TYPE_REAL_TIME = "REAL_TIME"; | |
| 53 | + private static final String PROJECT_TYPE_REAL_TIME_CN = "实时成交"; | |
| 54 | + | |
| 55 | + private static final String ORDER_BY_PRICE_ASC = "PRICE_ASC"; | |
| 56 | + private static final String ORDER_BY_CREATE_TIME_DESC = "CREATE_TIME_DESC"; | |
| 57 | + | |
| 58 | + @Resource | |
| 59 | + private SupplierQuotationProjectMapper supplierQuotationProjectMapper; | |
| 60 | + @Resource | |
| 61 | + private SysUserService sysUserService; | |
| 62 | + @Resource | |
| 63 | + private SysRoleService sysRoleService; | |
| 64 | + @Resource | |
| 65 | + private BreedRelationshipService breedRelationshipService; | |
| 66 | + | |
| 67 | + @OpLog(type = OtherOpLogType.class, name = "供应商报价项目报价,项目ID:{}", params = {"#vo.projectId"}) | |
| 68 | + @Transactional(rollbackFor = Exception.class) | |
| 69 | + @Override | |
| 70 | + public void quote(SupplierQuotationProjectQuoteVo vo) { | |
| 71 | + SupplierQuotationProject project = supplierQuotationProjectMapper.selectById(vo.getProjectId()); | |
| 72 | + if (project == null) { | |
| 73 | + throw new DefaultClientException("报价项目不存在!"); | |
| 74 | + } | |
| 75 | + validateProjectCanQuote(project); | |
| 76 | + validateProduct(vo.getProductId()); | |
| 77 | + | |
| 78 | + SysUser currentUser = getCurrentUser(); | |
| 79 | + LocalDateTime now = LocalDateTime.now(); | |
| 80 | + | |
| 81 | + SupplierQuotationProjectQuote exist = getBaseMapper() | |
| 82 | + .findByProjectAndSupplier(vo.getProjectId(), currentUser.getId()); | |
| 83 | + if (exist == null) { | |
| 84 | + SupplierQuotationProjectQuote data = new SupplierQuotationProjectQuote(); | |
| 85 | + data.setId(IdUtil.getId()); | |
| 86 | + data.setProjectId(StringUtils.trimToEmpty(vo.getProjectId())); | |
| 87 | + data.setSupplierId(currentUser.getId()); | |
| 88 | + data.setSupplierName(currentUser.getName()); | |
| 89 | + data.setQuoteTime(now); | |
| 90 | + data.setProductId(StringUtils.trimToEmpty(vo.getProductId())); | |
| 91 | + data.setQuantity(vo.getQuantity()); | |
| 92 | + data.setPrice(vo.getPrice()); | |
| 93 | + data.setBidStatus(null); | |
| 94 | + getBaseMapper().insert(data); | |
| 95 | + } else { | |
| 96 | + LambdaUpdateWrapper<SupplierQuotationProjectQuote> updateWrapper = Wrappers.lambdaUpdate(SupplierQuotationProjectQuote.class) | |
| 97 | + .set(SupplierQuotationProjectQuote::getSupplierName, currentUser.getName()) | |
| 98 | + .set(SupplierQuotationProjectQuote::getQuoteTime, now) | |
| 99 | + .set(SupplierQuotationProjectQuote::getProductId, StringUtils.trimToEmpty(vo.getProductId())) | |
| 100 | + .set(SupplierQuotationProjectQuote::getQuantity, vo.getQuantity()) | |
| 101 | + .set(SupplierQuotationProjectQuote::getPrice, vo.getPrice()) | |
| 102 | + .eq(SupplierQuotationProjectQuote::getId, exist.getId()); | |
| 103 | + getBaseMapper().update(updateWrapper); | |
| 104 | + } | |
| 105 | + | |
| 106 | + OpLogUtil.setExtra(vo); | |
| 107 | + } | |
| 108 | + | |
| 109 | + @Override | |
| 110 | + public SupplierQuotationProjectQuote getMyQuote(String projectId) { | |
| 111 | + SysUser currentUser = getCurrentUser(); | |
| 112 | + return getBaseMapper().findByProjectAndSupplier(projectId, currentUser.getId()); | |
| 113 | + } | |
| 114 | + | |
| 115 | + @Override | |
| 116 | + public List<SupplierQuotationProjectQuote> listByProject(String projectId) { | |
| 117 | + SupplierQuotationProject project = supplierQuotationProjectMapper.selectById(projectId); | |
| 118 | + if (project == null) { | |
| 119 | + throw new DefaultClientException("报价项目不存在!"); | |
| 120 | + } | |
| 121 | + | |
| 122 | + List<SysRole> sysRoleList = sysRoleService.getByUserId(SecurityUtil.getCurrentUser().getId()); | |
| 123 | + Set<String> roleCodeSet = sysRoleList.stream() | |
| 124 | + .map(SysRole::getCode) | |
| 125 | + .collect(Collectors.toSet()); | |
| 126 | + | |
| 127 | + if (roleCodeSet.contains("gys")) { | |
| 128 | + SupplierQuotationProjectQuote supplierQuotationProjectQuote = getMyQuote(projectId); | |
| 129 | + if (supplierQuotationProjectQuote == null) { | |
| 130 | + return Collections.emptyList(); | |
| 131 | + } | |
| 132 | + return Collections.singletonList(supplierQuotationProjectQuote); | |
| 133 | + } | |
| 134 | + | |
| 135 | + LocalDateTime now = LocalDateTime.now(); | |
| 136 | + boolean centralBid = isCentralBid(project.getProjectType()); | |
| 137 | + boolean realTime = isRealTime(project.getProjectType()); | |
| 138 | + boolean beforeBidTime = centralBid && project.getBidTime() != null && now.isBefore(project.getBidTime()); | |
| 139 | + | |
| 140 | + String orderBy = ORDER_BY_CREATE_TIME_DESC; | |
| 141 | + if (realTime) { | |
| 142 | + orderBy = ORDER_BY_PRICE_ASC; | |
| 143 | + } else if (centralBid && !beforeBidTime) { | |
| 144 | + orderBy = ORDER_BY_PRICE_ASC; | |
| 145 | + } | |
| 146 | + | |
| 147 | + List<SupplierQuotationProjectQuote> list = getBaseMapper().listByProject(projectId, orderBy); | |
| 148 | + if (beforeBidTime && CollectionUtil.isNotEmpty(list)) { | |
| 149 | + list.forEach(v -> v.setPrice(null)); | |
| 150 | + } | |
| 151 | + return list; | |
| 152 | + } | |
| 153 | + | |
| 154 | + @OpLog(type = OtherOpLogType.class, name = "维护供应商报价中标状态,项目ID:{},供应商ID:{}", params = {"#vo.projectId", "#vo.supplierId"}) | |
| 155 | + @Transactional(rollbackFor = Exception.class) | |
| 156 | + @Override | |
| 157 | + public void updateBidStatus(UpdateSupplierQuotationProjectQuoteBidStatusVo vo) { | |
| 158 | + String bidStatus = normalizeBidStatus(vo.getBidStatus()); | |
| 159 | + SupplierQuotationProjectQuote exist = getBaseMapper() | |
| 160 | + .findByProjectAndSupplier(vo.getProjectId(), vo.getSupplierId()); | |
| 161 | + if (ObjectUtil.isNull(exist)) { | |
| 162 | + throw new DefaultClientException("供应商报价记录不存在!"); | |
| 163 | + } | |
| 164 | + | |
| 165 | + LambdaUpdateWrapper<SupplierQuotationProjectQuote> updateWrapper = Wrappers.lambdaUpdate(SupplierQuotationProjectQuote.class) | |
| 166 | + .set(SupplierQuotationProjectQuote::getBidStatus, bidStatus) | |
| 167 | + .eq(SupplierQuotationProjectQuote::getId, exist.getId()); | |
| 168 | + getBaseMapper().update(updateWrapper); | |
| 169 | + | |
| 170 | + OpLogUtil.setExtra(vo); | |
| 171 | + } | |
| 172 | + | |
| 173 | + @Override | |
| 174 | + public void cleanCacheByKey(Serializable key) { | |
| 175 | + } | |
| 176 | + | |
| 177 | + private void validateProjectCanQuote(SupplierQuotationProject project) { | |
| 178 | + if (PROJECT_STATUS_COMPLETED.equals(project.getStatus())) { | |
| 179 | + throw new DefaultClientException("该报价项目已完成,不允许报价!"); | |
| 180 | + } | |
| 181 | + if (PROJECT_STATUS_ABORTED.equals(project.getStatus())) { | |
| 182 | + throw new DefaultClientException("该报价项目已中止,不允许报价!"); | |
| 183 | + } | |
| 184 | + | |
| 185 | + LocalDateTime now = LocalDateTime.now(); | |
| 186 | + if (project.getStartTime() != null && now.isBefore(project.getStartTime())) { | |
| 187 | + throw new DefaultClientException("该报价项目未开始,不允许报价!"); | |
| 188 | + } | |
| 189 | + if (project.getEndTime() != null && now.isAfter(project.getEndTime())) { | |
| 190 | + throw new DefaultClientException("该报价项目已截止,不允许报价!"); | |
| 191 | + } | |
| 192 | + } | |
| 193 | + | |
| 194 | + private void validateProduct(String productId) { | |
| 195 | + BreedRelationship breedRelationship = breedRelationshipService.findById(productId); | |
| 196 | + if (breedRelationship == null) { | |
| 197 | + throw new DefaultClientException("品种不存在,请重新选择!"); | |
| 198 | + } | |
| 199 | + } | |
| 200 | + | |
| 201 | + private SysUser getCurrentUser() { | |
| 202 | + String currentUserId = SecurityUtil.getCurrentUser().getId(); | |
| 203 | + SysUser currentUser = sysUserService.findById(currentUserId); | |
| 204 | + if (currentUser == null) { | |
| 205 | + throw new DefaultClientException("当前用户不存在!"); | |
| 206 | + } | |
| 207 | + return currentUser; | |
| 208 | + } | |
| 209 | + | |
| 210 | + private String normalizeBidStatus(String bidStatus) { | |
| 211 | + if (StringUtils.isBlank(bidStatus)) { | |
| 212 | + throw new DefaultClientException("中标状态不能为空!"); | |
| 213 | + } | |
| 214 | + if (BID_STATUS_WIN.equals(bidStatus) || BID_STATUS_LOSE.equals(bidStatus) || BID_STATUS_ABORT.equals(bidStatus)) { | |
| 215 | + return bidStatus; | |
| 216 | + } | |
| 217 | + throw new DefaultClientException("中标状态不合法!"); | |
| 218 | + } | |
| 219 | + | |
| 220 | + private boolean isCentralBid(String projectType) { | |
| 221 | + if (StringUtils.isBlank(projectType)) { | |
| 222 | + return false; | |
| 223 | + } | |
| 224 | + return PROJECT_TYPE_CENTRAL_BID.equalsIgnoreCase(projectType) || PROJECT_TYPE_CENTRAL_BID_CN.equals(projectType); | |
| 225 | + } | |
| 226 | + | |
| 227 | + private boolean isRealTime(String projectType) { | |
| 228 | + if (StringUtils.isBlank(projectType)) { | |
| 229 | + return false; | |
| 230 | + } | |
| 231 | + return PROJECT_TYPE_REAL_TIME.equalsIgnoreCase(projectType) || PROJECT_TYPE_REAL_TIME_CN.equals(projectType); | |
| 232 | + } | |
| 233 | +} | ... | ... |
| ... | ... | @@ -18,7 +18,9 @@ import com.lframework.starter.web.inner.components.oplog.OtherOpLogType; |
| 18 | 18 | import com.lframework.xingyun.basedata.entity.BreedRelationship; |
| 19 | 19 | import com.lframework.xingyun.basedata.service.breed.BreedRelationshipService; |
| 20 | 20 | import com.lframework.xingyun.sc.procurement.entity.SupplierQuotationProject; |
| 21 | +import com.lframework.xingyun.sc.procurement.entity.SupplierQuotationProjectQuote; | |
| 21 | 22 | import com.lframework.xingyun.sc.procurement.mappers.quotation.SupplierQuotationProjectMapper; |
| 23 | +import com.lframework.xingyun.sc.procurement.service.quotation.SupplierQuotationProjectQuoteService; | |
| 22 | 24 | import com.lframework.xingyun.sc.procurement.service.quotation.SupplierQuotationProjectService; |
| 23 | 25 | import com.lframework.xingyun.sc.procurement.vo.quotation.CreateSupplierQuotationProjectVo; |
| 24 | 26 | import com.lframework.xingyun.sc.procurement.vo.quotation.QuerySupplierQuotationProjectVo; |
| ... | ... | @@ -53,10 +55,10 @@ public class SupplierQuotationProjectServiceImpl |
| 53 | 55 | //已中止 |
| 54 | 56 | private static final String STATUS_ABORTED_CN = "ABORTED"; |
| 55 | 57 | |
| 56 | - | |
| 57 | - | |
| 58 | 58 | @Resource |
| 59 | 59 | private BreedRelationshipService breedRelationshipService; |
| 60 | + @Resource | |
| 61 | + private SupplierQuotationProjectQuoteService supplierQuotationProjectQuoteService; | |
| 60 | 62 | |
| 61 | 63 | @Override |
| 62 | 64 | public PageResult<SupplierQuotationProject> query(Integer pageIndex, Integer pageSize, QuerySupplierQuotationProjectVo vo) { |
| ... | ... | @@ -80,6 +82,8 @@ public class SupplierQuotationProjectServiceImpl |
| 80 | 82 | SupplierQuotationProject data = getBaseMapper().findById(id); |
| 81 | 83 | if (data != null) { |
| 82 | 84 | data.setStatus(computeStatus(data)); |
| 85 | + List<SupplierQuotationProjectQuote> supplierQuotationProjectQuoteList = supplierQuotationProjectQuoteService.listByProject(id); | |
| 86 | + data.setSupplierQuotationProjectQuoteList(supplierQuotationProjectQuoteList); | |
| 83 | 87 | } |
| 84 | 88 | return data; |
| 85 | 89 | } | ... | ... |
| 1 | +package com.lframework.xingyun.sc.procurement.mappers.quotation; | |
| 2 | + | |
| 3 | +import com.lframework.starter.web.core.mapper.BaseMapper; | |
| 4 | +import com.lframework.xingyun.sc.procurement.entity.SupplierQuotationProjectQuote; | |
| 5 | +import java.util.List; | |
| 6 | +import org.apache.ibatis.annotations.Param; | |
| 7 | + | |
| 8 | +public interface SupplierQuotationProjectQuoteMapper extends BaseMapper<SupplierQuotationProjectQuote> { | |
| 9 | + | |
| 10 | + SupplierQuotationProjectQuote findByProjectAndSupplier(@Param("projectId") String projectId, | |
| 11 | + @Param("supplierId") String supplierId); | |
| 12 | + | |
| 13 | + List<SupplierQuotationProjectQuote> listByProject(@Param("projectId") String projectId, | |
| 14 | + @Param("orderBy") String orderBy); | |
| 15 | +} | ... | ... |
| 1 | +package com.lframework.xingyun.sc.procurement.service.quotation; | |
| 2 | + | |
| 3 | +import com.lframework.starter.web.core.service.BaseMpService; | |
| 4 | +import com.lframework.xingyun.sc.procurement.entity.SupplierQuotationProjectQuote; | |
| 5 | +import com.lframework.xingyun.sc.procurement.vo.quotation.SupplierQuotationProjectQuoteVo; | |
| 6 | +import com.lframework.xingyun.sc.procurement.vo.quotation.UpdateSupplierQuotationProjectQuoteBidStatusVo; | |
| 7 | +import java.util.List; | |
| 8 | + | |
| 9 | +public interface SupplierQuotationProjectQuoteService extends BaseMpService<SupplierQuotationProjectQuote> { | |
| 10 | + | |
| 11 | + void quote(SupplierQuotationProjectQuoteVo vo); | |
| 12 | + | |
| 13 | + SupplierQuotationProjectQuote getMyQuote(String projectId); | |
| 14 | + | |
| 15 | + List<SupplierQuotationProjectQuote> listByProject(String projectId); | |
| 16 | + | |
| 17 | + void updateBidStatus(UpdateSupplierQuotationProjectQuoteBidStatusVo vo); | |
| 18 | +} | |
| 19 | + | ... | ... |
| 1 | +package com.lframework.xingyun.sc.procurement.vo.quotation; | |
| 2 | + | |
| 3 | +import com.lframework.starter.web.core.vo.BaseVo; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import java.io.Serializable; | |
| 6 | +import java.math.BigDecimal; | |
| 7 | +import java.time.LocalDateTime; | |
| 8 | +import javax.validation.constraints.NotBlank; | |
| 9 | +import javax.validation.constraints.NotNull; | |
| 10 | +import lombok.Data; | |
| 11 | + | |
| 12 | +@Data | |
| 13 | +public class SupplierQuotationProjectQuoteVo implements BaseVo, Serializable { | |
| 14 | + | |
| 15 | + private static final long serialVersionUID = 1L; | |
| 16 | + | |
| 17 | + @ApiModelProperty(value = "报价项目ID", required = true) | |
| 18 | + @NotBlank(message = "报价项目ID不能为空!") | |
| 19 | + private String projectId; | |
| 20 | + | |
| 21 | + @ApiModelProperty(value = "品种ID", required = true) | |
| 22 | + @NotBlank(message = "品种不能为空!") | |
| 23 | + private String productId; | |
| 24 | + | |
| 25 | + @ApiModelProperty(value = "数量", required = true) | |
| 26 | + @NotNull(message = "数量不能为空!") | |
| 27 | + private BigDecimal quantity; | |
| 28 | + | |
| 29 | + @ApiModelProperty(value = "价格", required = true) | |
| 30 | + @NotNull(message = "价格不能为空!") | |
| 31 | + private BigDecimal price; | |
| 32 | + | |
| 33 | + @ApiModelProperty("报价时间(前端不传,后端以当前时间写入)") | |
| 34 | + private LocalDateTime quoteTime; | |
| 35 | +} | |
| 36 | + | ... | ... |
| 1 | +package com.lframework.xingyun.sc.procurement.vo.quotation; | |
| 2 | + | |
| 3 | +import com.lframework.starter.web.core.vo.BaseVo; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import java.io.Serializable; | |
| 6 | +import javax.validation.constraints.NotBlank; | |
| 7 | +import lombok.Data; | |
| 8 | + | |
| 9 | +@Data | |
| 10 | +public class UpdateSupplierQuotationProjectQuoteBidStatusVo implements BaseVo, Serializable { | |
| 11 | + | |
| 12 | + private static final long serialVersionUID = 1L; | |
| 13 | + | |
| 14 | + @ApiModelProperty(value = "报价项目ID", required = true) | |
| 15 | + @NotBlank(message = "报价项目ID不能为空!") | |
| 16 | + private String projectId; | |
| 17 | + | |
| 18 | + @ApiModelProperty(value = "供应商ID(当前登录用户ID)", required = true) | |
| 19 | + @NotBlank(message = "供应商ID不能为空!") | |
| 20 | + private String supplierId; | |
| 21 | + | |
| 22 | + @ApiModelProperty(value = "中标状态(中标/未中标/废标)", required = true) | |
| 23 | + @NotBlank(message = "中标状态不能为空!") | |
| 24 | + private String bidStatus; | |
| 25 | +} | |
| 26 | + | ... | ... |
xingyun-sc/src/main/resources/mappers/procurement/quotation/SupplierQuotationProjectQuoteMapper.xml
0 → 100644
| 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.procurement.mappers.quotation.SupplierQuotationProjectQuoteMapper"> | |
| 4 | + | |
| 5 | + <resultMap id="SupplierQuotationProjectQuote" type="com.lframework.xingyun.sc.procurement.entity.SupplierQuotationProjectQuote"> | |
| 6 | + <id column="id" property="id"/> | |
| 7 | + <result column="project_id" property="projectId"/> | |
| 8 | + <result column="supplier_id" property="supplierId"/> | |
| 9 | + <result column="supplier_name" property="supplierName"/> | |
| 10 | + <result column="quote_time" property="quoteTime"/> | |
| 11 | + <result column="product_id" property="productId"/> | |
| 12 | + <result column="product_name" property="productName"/> | |
| 13 | + <result column="product_code" property="productCode"/> | |
| 14 | + <result column="quantity" property="quantity"/> | |
| 15 | + <result column="price" property="price"/> | |
| 16 | + <result column="bid_status" property="bidStatus"/> | |
| 17 | + <result column="create_by_id" property="createById"/> | |
| 18 | + <result column="create_by" property="createBy"/> | |
| 19 | + <result column="update_by_id" property="updateById"/> | |
| 20 | + <result column="update_by" property="updateBy"/> | |
| 21 | + <result column="create_time" property="createTime"/> | |
| 22 | + <result column="update_time" property="updateTime"/> | |
| 23 | + </resultMap> | |
| 24 | + | |
| 25 | + <sql id="SupplierQuotationProjectQuoteSql"> | |
| 26 | + SELECT | |
| 27 | + tb.id, | |
| 28 | + tb.project_id, | |
| 29 | + tb.supplier_id, | |
| 30 | + tb.supplier_name, | |
| 31 | + tb.quote_time, | |
| 32 | + tb.product_id, | |
| 33 | + br.product_name, | |
| 34 | + br.code AS product_code, | |
| 35 | + tb.quantity, | |
| 36 | + tb.price, | |
| 37 | + tb.bid_status, | |
| 38 | + tb.create_by_id, | |
| 39 | + tb.create_by, | |
| 40 | + tb.update_by_id, | |
| 41 | + tb.update_by, | |
| 42 | + tb.create_time, | |
| 43 | + tb.update_time | |
| 44 | + FROM procurement_supplier_quotation_project_quote tb | |
| 45 | + LEFT JOIN base_data_breed_relationship br ON br.id = tb.product_id | |
| 46 | + </sql> | |
| 47 | + | |
| 48 | + <select id="findByProjectAndSupplier" resultMap="SupplierQuotationProjectQuote"> | |
| 49 | + <include refid="SupplierQuotationProjectQuoteSql"/> | |
| 50 | + WHERE tb.project_id = #{projectId} | |
| 51 | + AND tb.supplier_id = #{supplierId} | |
| 52 | + </select> | |
| 53 | + | |
| 54 | + <select id="listByProject" resultMap="SupplierQuotationProjectQuote"> | |
| 55 | + <include refid="SupplierQuotationProjectQuoteSql"/> | |
| 56 | + WHERE tb.project_id = #{projectId} | |
| 57 | + <choose> | |
| 58 | + <when test="orderBy == 'PRICE_ASC'"> | |
| 59 | + ORDER BY tb.price ASC, tb.quote_time DESC, tb.id DESC | |
| 60 | + </when> | |
| 61 | + <otherwise> | |
| 62 | + ORDER BY tb.create_time DESC, tb.id DESC | |
| 63 | + </otherwise> | |
| 64 | + </choose> | |
| 65 | + </select> | |
| 66 | +</mapper> | ... | ... |