feat: 需求工单管理模块完整实现

## 新增功能

### 需求工单实体层
- Requirement.java: 需求工单实体类
- RequirementMapper.java: MyBatis-Plus Mapper接口
- RequirementDataService.java: 数据访问服务

### 业务层
- RequirementDTO.java: 数据传输对象
- RequirementVO.java: 视图对象
- RequirementService.java: 业务服务实现

### 接口层
- RequirementController.java: REST API接口
  - GET /api/v1/requirement/list - 分页查询
  - GET /api/v1/requirement/{id} - 查询详情
  - POST /api/v1/requirement - 创建需求
  - PUT /api/v1/requirement/{id} - 更新需求
  - DELETE /api/v1/requirement/{id} - 删除需求
  - PUT /api/v1/requirement/{id}/status - 更新状态
  - PUT /api/v1/requirement/{id}/progress - 更新进度

### 数据库
- requirement.sql: 建表SQL脚本
This commit is contained in:
zhangjf 2026-02-17 15:34:40 +08:00
parent da445a44de
commit 075525d577
8 changed files with 1098 additions and 0 deletions

34
doc/requirement.sql Normal file
View File

@ -0,0 +1,34 @@
-- 需求工单表
CREATE TABLE IF NOT EXISTS `requirement` (
`requirement_id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键需求ID',
`tenant_id` BIGINT NOT NULL COMMENT '租户ID',
`requirement_code` VARCHAR(50) NOT NULL COMMENT '需求编号',
`requirement_name` VARCHAR(200) NOT NULL COMMENT '需求名称',
`description` TEXT COMMENT '需求描述',
`project_id` BIGINT NOT NULL COMMENT '项目ID',
`customer_id` BIGINT NOT NULL COMMENT '客户ID',
`priority` VARCHAR(20) DEFAULT 'normal' COMMENT '优先级high-高normal-中low-低',
`estimated_hours` DECIMAL(8,2) DEFAULT 0.00 COMMENT '预估开发工时(小时)',
`actual_hours` DECIMAL(8,2) DEFAULT 0.00 COMMENT '实际开发工时(小时)',
`planned_start` DATE COMMENT '计划开始日期',
`planned_end` DATE COMMENT '计划结束日期',
`actual_start` DATE COMMENT '实际开始日期',
`actual_end` DATE COMMENT '实际结束日期',
`delivery_date` DATE COMMENT '交付日期',
`receivable_amount` DECIMAL(15,2) DEFAULT 0.00 COMMENT '应收款金额',
`receivable_date` DATE COMMENT '应收款日期',
`status` VARCHAR(20) DEFAULT 'pending' COMMENT '状态pending-待开发developing-开发中delivered-已交付completed-已完成',
`progress` INT DEFAULT 0 COMMENT '开发进度0-100',
`attachment_url` VARCHAR(500) COMMENT '附件URL',
`created_by` BIGINT COMMENT '创建人ID',
`created_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_by` BIGINT COMMENT '更新人ID',
`updated_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` TINYINT DEFAULT 0 COMMENT '逻辑删除0-未删除1-已删除',
PRIMARY KEY (`requirement_id`),
UNIQUE KEY `uk_tenant_code` (`tenant_id`, `requirement_code`),
INDEX `idx_tenant` (`tenant_id`),
INDEX `idx_project` (`project_id`),
INDEX `idx_customer` (`customer_id`),
INDEX `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='需求工单表';

View File

@ -0,0 +1,104 @@
package com.fundplatform.proj.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fundplatform.common.core.Result;
import com.fundplatform.proj.dto.RequirementDTO;
import com.fundplatform.proj.service.RequirementService;
import com.fundplatform.proj.vo.RequirementVO;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* 需求工单Controller
*/
@RestController
@RequestMapping("/api/v1/requirement")
public class RequirementController {
@Autowired
private RequirementService requirementService;
/**
* 分页查询需求工单列表
*/
@GetMapping("/list")
public Result<Page<RequirementVO>> list(
@RequestHeader("X-Tenant-Id") Long tenantId,
@RequestParam(required = false) String requirementName,
@RequestParam(required = false) String status,
@RequestParam(required = false) Long projectId,
@RequestParam(required = false) Long customerId,
@RequestParam(defaultValue = "1") int current,
@RequestParam(defaultValue = "10") int size) {
return requirementService.page(tenantId, requirementName, status, projectId, customerId, current, size);
}
/**
* 查询需求工单详情
*/
@GetMapping("/{requirementId}")
public Result<RequirementVO> get(
@RequestHeader("X-Tenant-Id") Long tenantId,
@PathVariable Long requirementId) {
return requirementService.getById(tenantId, requirementId);
}
/**
* 创建需求工单
*/
@PostMapping
public Result<RequirementVO> create(
@RequestHeader("X-Tenant-Id") Long tenantId,
@RequestHeader("X-User-Id") Long userId,
@Valid @RequestBody RequirementDTO dto) {
return requirementService.create(tenantId, userId, dto);
}
/**
* 更新需求工单
*/
@PutMapping("/{requirementId}")
public Result<RequirementVO> update(
@RequestHeader("X-Tenant-Id") Long tenantId,
@RequestHeader("X-User-Id") Long userId,
@PathVariable Long requirementId,
@Valid @RequestBody RequirementDTO dto) {
return requirementService.update(tenantId, userId, requirementId, dto);
}
/**
* 删除需求工单
*/
@DeleteMapping("/{requirementId}")
public Result<Void> delete(
@RequestHeader("X-Tenant-Id") Long tenantId,
@RequestHeader("X-User-Id") Long userId,
@PathVariable Long requirementId) {
return requirementService.delete(tenantId, userId, requirementId);
}
/**
* 更新需求状态
*/
@PutMapping("/{requirementId}/status")
public Result<RequirementVO> updateStatus(
@RequestHeader("X-Tenant-Id") Long tenantId,
@RequestHeader("X-User-Id") Long userId,
@PathVariable Long requirementId,
@RequestParam String status) {
return requirementService.updateStatus(tenantId, userId, requirementId, status);
}
/**
* 更新开发进度
*/
@PutMapping("/{requirementId}/progress")
public Result<RequirementVO> updateProgress(
@RequestHeader("X-Tenant-Id") Long tenantId,
@RequestHeader("X-User-Id") Long userId,
@PathVariable Long requirementId,
@RequestParam Integer progress) {
return requirementService.updateProgress(tenantId, userId, requirementId, progress);
}
}

View File

@ -0,0 +1,213 @@
package com.fundplatform.proj.data.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fundplatform.common.core.BaseEntity;
import java.math.BigDecimal;
import java.time.LocalDate;
/**
* 需求工单实体
*/
@TableName("requirement")
public class Requirement extends BaseEntity {
/** 需求编号 */
private String requirementCode;
/** 需求名称 */
private String requirementName;
/** 需求描述 */
private String description;
/** 项目ID */
private Long projectId;
/** 客户ID */
private Long customerId;
/** 优先级(high-高normal-中low-低) */
private String priority;
/** 预估开发工时(小时) */
private BigDecimal estimatedHours;
/** 实际开发工时(小时) */
private BigDecimal actualHours;
/** 计划开始日期 */
private LocalDate plannedStart;
/** 计划结束日期 */
private LocalDate plannedEnd;
/** 实际开始日期 */
private LocalDate actualStart;
/** 实际结束日期 */
private LocalDate actualEnd;
/** 交付日期 */
private LocalDate deliveryDate;
/** 应收款金额 */
private BigDecimal receivableAmount;
/** 应收款日期 */
private LocalDate receivableDate;
/** 状态(pending-待开发developing-开发中delivered-已交付completed-已完成) */
private String status;
/** 开发进度(0-100) */
private Integer progress;
/** 附件URL */
private String attachmentUrl;
public String getRequirementCode() {
return requirementCode;
}
public void setRequirementCode(String requirementCode) {
this.requirementCode = requirementCode;
}
public String getRequirementName() {
return requirementName;
}
public void setRequirementName(String requirementName) {
this.requirementName = requirementName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Long getProjectId() {
return projectId;
}
public void setProjectId(Long projectId) {
this.projectId = projectId;
}
public Long getCustomerId() {
return customerId;
}
public void setCustomerId(Long customerId) {
this.customerId = customerId;
}
public String getPriority() {
return priority;
}
public void setPriority(String priority) {
this.priority = priority;
}
public BigDecimal getEstimatedHours() {
return estimatedHours;
}
public void setEstimatedHours(BigDecimal estimatedHours) {
this.estimatedHours = estimatedHours;
}
public BigDecimal getActualHours() {
return actualHours;
}
public void setActualHours(BigDecimal actualHours) {
this.actualHours = actualHours;
}
public LocalDate getPlannedStart() {
return plannedStart;
}
public void setPlannedStart(LocalDate plannedStart) {
this.plannedStart = plannedStart;
}
public LocalDate getPlannedEnd() {
return plannedEnd;
}
public void setPlannedEnd(LocalDate plannedEnd) {
this.plannedEnd = plannedEnd;
}
public LocalDate getActualStart() {
return actualStart;
}
public void setActualStart(LocalDate actualStart) {
this.actualStart = actualStart;
}
public LocalDate getActualEnd() {
return actualEnd;
}
public void setActualEnd(LocalDate actualEnd) {
this.actualEnd = actualEnd;
}
public LocalDate getDeliveryDate() {
return deliveryDate;
}
public void setDeliveryDate(LocalDate deliveryDate) {
this.deliveryDate = deliveryDate;
}
public BigDecimal getReceivableAmount() {
return receivableAmount;
}
public void setReceivableAmount(BigDecimal receivableAmount) {
this.receivableAmount = receivableAmount;
}
public LocalDate getReceivableDate() {
return receivableDate;
}
public void setReceivableDate(LocalDate receivableDate) {
this.receivableDate = receivableDate;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Integer getProgress() {
return progress;
}
public void setProgress(Integer progress) {
this.progress = progress;
}
public String getAttachmentUrl() {
return attachmentUrl;
}
public void setAttachmentUrl(String attachmentUrl) {
this.attachmentUrl = attachmentUrl;
}
}

View File

@ -0,0 +1,12 @@
package com.fundplatform.proj.data.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fundplatform.proj.data.entity.Requirement;
import org.apache.ibatis.annotations.Mapper;
/**
* 需求工单Mapper
*/
@Mapper
public interface RequirementMapper extends BaseMapper<Requirement> {
}

View File

@ -0,0 +1,13 @@
package com.fundplatform.proj.data.service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fundplatform.proj.data.entity.Requirement;
import com.fundplatform.proj.data.mapper.RequirementMapper;
import org.springframework.stereotype.Service;
/**
* 需求工单数据服务
*/
@Service
public class RequirementDataService extends ServiceImpl<RequirementMapper, Requirement> {
}

View File

@ -0,0 +1,207 @@
package com.fundplatform.proj.dto;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.time.LocalDate;
/**
* 需求工单DTO
*/
public class RequirementDTO {
private Long requirementId;
@NotBlank(message = "需求编号不能为空")
private String requirementCode;
@NotBlank(message = "需求名称不能为空")
private String requirementName;
private String description;
@NotNull(message = "项目ID不能为空")
private Long projectId;
@NotNull(message = "客户ID不能为空")
private Long customerId;
private String priority;
private BigDecimal estimatedHours;
private BigDecimal actualHours;
private LocalDate plannedStart;
private LocalDate plannedEnd;
private LocalDate actualStart;
private LocalDate actualEnd;
private LocalDate deliveryDate;
private BigDecimal receivableAmount;
private LocalDate receivableDate;
private String status;
private Integer progress;
private String attachmentUrl;
public Long getRequirementId() {
return requirementId;
}
public void setRequirementId(Long requirementId) {
this.requirementId = requirementId;
}
public String getRequirementCode() {
return requirementCode;
}
public void setRequirementCode(String requirementCode) {
this.requirementCode = requirementCode;
}
public String getRequirementName() {
return requirementName;
}
public void setRequirementName(String requirementName) {
this.requirementName = requirementName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Long getProjectId() {
return projectId;
}
public void setProjectId(Long projectId) {
this.projectId = projectId;
}
public Long getCustomerId() {
return customerId;
}
public void setCustomerId(Long customerId) {
this.customerId = customerId;
}
public String getPriority() {
return priority;
}
public void setPriority(String priority) {
this.priority = priority;
}
public BigDecimal getEstimatedHours() {
return estimatedHours;
}
public void setEstimatedHours(BigDecimal estimatedHours) {
this.estimatedHours = estimatedHours;
}
public BigDecimal getActualHours() {
return actualHours;
}
public void setActualHours(BigDecimal actualHours) {
this.actualHours = actualHours;
}
public LocalDate getPlannedStart() {
return plannedStart;
}
public void setPlannedStart(LocalDate plannedStart) {
this.plannedStart = plannedStart;
}
public LocalDate getPlannedEnd() {
return plannedEnd;
}
public void setPlannedEnd(LocalDate plannedEnd) {
this.plannedEnd = plannedEnd;
}
public LocalDate getActualStart() {
return actualStart;
}
public void setActualStart(LocalDate actualStart) {
this.actualStart = actualStart;
}
public LocalDate getActualEnd() {
return actualEnd;
}
public void setActualEnd(LocalDate actualEnd) {
this.actualEnd = actualEnd;
}
public LocalDate getDeliveryDate() {
return deliveryDate;
}
public void setDeliveryDate(LocalDate deliveryDate) {
this.deliveryDate = deliveryDate;
}
public BigDecimal getReceivableAmount() {
return receivableAmount;
}
public void setReceivableAmount(BigDecimal receivableAmount) {
this.receivableAmount = receivableAmount;
}
public LocalDate getReceivableDate() {
return receivableDate;
}
public void setReceivableDate(LocalDate receivableDate) {
this.receivableDate = receivableDate;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Integer getProgress() {
return progress;
}
public void setProgress(Integer progress) {
this.progress = progress;
}
public String getAttachmentUrl() {
return attachmentUrl;
}
public void setAttachmentUrl(String attachmentUrl) {
this.attachmentUrl = attachmentUrl;
}
}

View File

@ -0,0 +1,269 @@
package com.fundplatform.proj.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fundplatform.common.core.Result;
import com.fundplatform.proj.data.entity.Requirement;
import com.fundplatform.proj.data.service.RequirementDataService;
import com.fundplatform.proj.dto.RequirementDTO;
import com.fundplatform.proj.vo.RequirementVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
/**
* 需求工单业务服务
*/
@Service
public class RequirementService {
private static final Logger log = LoggerFactory.getLogger(RequirementService.class);
@Autowired
private RequirementDataService requirementDataService;
private static final Map<String, String> STATUS_MAP = new HashMap<>();
private static final Map<String, String> PRIORITY_MAP = new HashMap<>();
static {
STATUS_MAP.put("pending", "待开发");
STATUS_MAP.put("developing", "开发中");
STATUS_MAP.put("delivered", "已交付");
STATUS_MAP.put("completed", "已完成");
PRIORITY_MAP.put("high", "");
PRIORITY_MAP.put("normal", "");
PRIORITY_MAP.put("low", "");
}
/**
* 分页查询需求工单
*/
public Result<Page<RequirementVO>> page(Long tenantId, String requirementName, String status,
Long projectId, Long customerId, int current, int size) {
Page<Requirement> page = new Page<>(current, size);
LambdaQueryWrapper<Requirement> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Requirement::getTenantId, tenantId);
wrapper.eq(Requirement::getDeleted, 0);
if (StringUtils.hasText(requirementName)) {
wrapper.like(Requirement::getRequirementName, requirementName);
}
if (StringUtils.hasText(status)) {
wrapper.eq(Requirement::getStatus, status);
}
if (projectId != null) {
wrapper.eq(Requirement::getProjectId, projectId);
}
if (customerId != null) {
wrapper.eq(Requirement::getCustomerId, customerId);
}
wrapper.orderByDesc(Requirement::getCreatedTime);
Page<Requirement> result = requirementDataService.page(page, wrapper);
Page<RequirementVO> voPage = new Page<>(result.getCurrent(), result.getSize(), result.getTotal());
voPage.setRecords(result.getRecords().stream().map(this::toVO).toList());
return Result.success(voPage);
}
/**
* 查询需求工单详情
*/
public Result<RequirementVO> getById(Long tenantId, Long requirementId) {
Requirement requirement = requirementDataService.getOne(
new LambdaQueryWrapper<Requirement>()
.eq(Requirement::getId, requirementId)
.eq(Requirement::getTenantId, tenantId)
.eq(Requirement::getDeleted, 0)
);
if (requirement == null) {
return Result.error("需求工单不存在");
}
return Result.success(toVO(requirement));
}
/**
* 创建需求工单
*/
@Transactional
public Result<RequirementVO> create(Long tenantId, Long userId, RequirementDTO dto) {
// 检查编号唯一性
long count = requirementDataService.count(
new LambdaQueryWrapper<Requirement>()
.eq(Requirement::getTenantId, tenantId)
.eq(Requirement::getRequirementCode, dto.getRequirementCode())
);
if (count > 0) {
return Result.error("需求编号已存在");
}
Requirement requirement = new Requirement();
BeanUtils.copyProperties(dto, requirement);
requirement.setTenantId(tenantId);
requirement.setCreatedBy(userId);
requirement.setCreatedTime(LocalDateTime.now());
requirement.setUpdatedBy(userId);
requirement.setUpdatedTime(LocalDateTime.now());
requirement.setDeleted(0);
// 默认值
if (!StringUtils.hasText(requirement.getStatus())) {
requirement.setStatus("pending");
}
if (!StringUtils.hasText(requirement.getPriority())) {
requirement.setPriority("normal");
}
if (requirement.getProgress() == null) {
requirement.setProgress(0);
}
requirementDataService.save(requirement);
log.info("创建需求工单: {} - {}", requirement.getRequirementCode(), requirement.getRequirementName());
return Result.success(toVO(requirement));
}
/**
* 更新需求工单
*/
@Transactional
public Result<RequirementVO> update(Long tenantId, Long userId, Long requirementId, RequirementDTO dto) {
Requirement requirement = requirementDataService.getOne(
new LambdaQueryWrapper<Requirement>()
.eq(Requirement::getId, requirementId)
.eq(Requirement::getTenantId, tenantId)
.eq(Requirement::getDeleted, 0)
);
if (requirement == null) {
return Result.error("需求工单不存在");
}
// 检查编号唯一性排除自身
if (!requirement.getRequirementCode().equals(dto.getRequirementCode())) {
long count = requirementDataService.count(
new LambdaQueryWrapper<Requirement>()
.eq(Requirement::getTenantId, tenantId)
.eq(Requirement::getRequirementCode, dto.getRequirementCode())
.ne(Requirement::getId, requirementId)
);
if (count > 0) {
return Result.error("需求编号已存在");
}
}
BeanUtils.copyProperties(dto, requirement, "id", "tenantId", "createdBy", "createdTime", "deleted");
requirement.setId(requirementId);
requirement.setUpdatedBy(userId);
requirement.setUpdatedTime(LocalDateTime.now());
requirementDataService.updateById(requirement);
log.info("更新需求工单: {}", requirement.getRequirementCode());
return Result.success(toVO(requirement));
}
/**
* 删除需求工单
*/
@Transactional
public Result<Void> delete(Long tenantId, Long userId, Long requirementId) {
Requirement requirement = requirementDataService.getOne(
new LambdaQueryWrapper<Requirement>()
.eq(Requirement::getId, requirementId)
.eq(Requirement::getTenantId, tenantId)
.eq(Requirement::getDeleted, 0)
);
if (requirement == null) {
return Result.error("需求工单不存在");
}
requirement.setDeleted(1);
requirement.setUpdatedBy(userId);
requirement.setUpdatedTime(LocalDateTime.now());
requirementDataService.updateById(requirement);
log.info("删除需求工单: {}", requirement.getRequirementCode());
return Result.success();
}
/**
* 更新需求状态
*/
@Transactional
public Result<RequirementVO> updateStatus(Long tenantId, Long userId, Long requirementId, String status) {
Requirement requirement = requirementDataService.getOne(
new LambdaQueryWrapper<Requirement>()
.eq(Requirement::getId, requirementId)
.eq(Requirement::getTenantId, tenantId)
.eq(Requirement::getDeleted, 0)
);
if (requirement == null) {
return Result.error("需求工单不存在");
}
requirement.setStatus(status);
requirement.setUpdatedBy(userId);
requirement.setUpdatedTime(LocalDateTime.now());
requirementDataService.updateById(requirement);
log.info("更新需求工单状态: {} -> {}", requirement.getRequirementCode(), status);
return Result.success(toVO(requirement));
}
/**
* 更新开发进度
*/
@Transactional
public Result<RequirementVO> updateProgress(Long tenantId, Long userId, Long requirementId, Integer progress) {
Requirement requirement = requirementDataService.getOne(
new LambdaQueryWrapper<Requirement>()
.eq(Requirement::getId, requirementId)
.eq(Requirement::getTenantId, tenantId)
.eq(Requirement::getDeleted, 0)
);
if (requirement == null) {
return Result.error("需求工单不存在");
}
requirement.setProgress(progress);
requirement.setUpdatedBy(userId);
requirement.setUpdatedTime(LocalDateTime.now());
requirementDataService.updateById(requirement);
log.info("更新需求工单进度: {} -> {}%", requirement.getRequirementCode(), progress);
return Result.success(toVO(requirement));
}
private RequirementVO toVO(Requirement requirement) {
RequirementVO vo = new RequirementVO();
BeanUtils.copyProperties(requirement, vo);
vo.setRequirementId(requirement.getId());
vo.setStatusName(STATUS_MAP.getOrDefault(requirement.getStatus(), requirement.getStatus()));
vo.setPriorityName(PRIORITY_MAP.getOrDefault(requirement.getPriority(), requirement.getPriority()));
return vo;
}
}

View File

@ -0,0 +1,246 @@
package com.fundplatform.proj.vo;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 需求工单VO
*/
public class RequirementVO {
private Long requirementId;
private String requirementCode;
private String requirementName;
private String description;
private Long projectId;
private String projectName;
private Long customerId;
private String customerName;
private String priority;
private String priorityName;
private BigDecimal estimatedHours;
private BigDecimal actualHours;
private LocalDate plannedStart;
private LocalDate plannedEnd;
private LocalDate actualStart;
private LocalDate actualEnd;
private LocalDate deliveryDate;
private BigDecimal receivableAmount;
private LocalDate receivableDate;
private String status;
private String statusName;
private Integer progress;
private String attachmentUrl;
private Long tenantId;
private LocalDateTime createdTime;
private LocalDateTime updatedTime;
public Long getRequirementId() {
return requirementId;
}
public void setRequirementId(Long requirementId) {
this.requirementId = requirementId;
}
public String getRequirementCode() {
return requirementCode;
}
public void setRequirementCode(String requirementCode) {
this.requirementCode = requirementCode;
}
public String getRequirementName() {
return requirementName;
}
public void setRequirementName(String requirementName) {
this.requirementName = requirementName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Long getProjectId() {
return projectId;
}
public void setProjectId(Long projectId) {
this.projectId = projectId;
}
public String getProjectName() {
return projectName;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
public Long getCustomerId() {
return customerId;
}
public void setCustomerId(Long customerId) {
this.customerId = customerId;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getPriority() {
return priority;
}
public void setPriority(String priority) {
this.priority = priority;
}
public String getPriorityName() {
return priorityName;
}
public void setPriorityName(String priorityName) {
this.priorityName = priorityName;
}
public BigDecimal getEstimatedHours() {
return estimatedHours;
}
public void setEstimatedHours(BigDecimal estimatedHours) {
this.estimatedHours = estimatedHours;
}
public BigDecimal getActualHours() {
return actualHours;
}
public void setActualHours(BigDecimal actualHours) {
this.actualHours = actualHours;
}
public LocalDate getPlannedStart() {
return plannedStart;
}
public void setPlannedStart(LocalDate plannedStart) {
this.plannedStart = plannedStart;
}
public LocalDate getPlannedEnd() {
return plannedEnd;
}
public void setPlannedEnd(LocalDate plannedEnd) {
this.plannedEnd = plannedEnd;
}
public LocalDate getActualStart() {
return actualStart;
}
public void setActualStart(LocalDate actualStart) {
this.actualStart = actualStart;
}
public LocalDate getActualEnd() {
return actualEnd;
}
public void setActualEnd(LocalDate actualEnd) {
this.actualEnd = actualEnd;
}
public LocalDate getDeliveryDate() {
return deliveryDate;
}
public void setDeliveryDate(LocalDate deliveryDate) {
this.deliveryDate = deliveryDate;
}
public BigDecimal getReceivableAmount() {
return receivableAmount;
}
public void setReceivableAmount(BigDecimal receivableAmount) {
this.receivableAmount = receivableAmount;
}
public LocalDate getReceivableDate() {
return receivableDate;
}
public void setReceivableDate(LocalDate receivableDate) {
this.receivableDate = receivableDate;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getStatusName() {
return statusName;
}
public void setStatusName(String statusName) {
this.statusName = statusName;
}
public Integer getProgress() {
return progress;
}
public void setProgress(Integer progress) {
this.progress = progress;
}
public String getAttachmentUrl() {
return attachmentUrl;
}
public void setAttachmentUrl(String attachmentUrl) {
this.attachmentUrl = attachmentUrl;
}
public Long getTenantId() {
return tenantId;
}
public void setTenantId(Long tenantId) {
this.tenantId = tenantId;
}
public LocalDateTime getCreatedTime() {
return createdTime;
}
public void setCreatedTime(LocalDateTime createdTime) {
this.createdTime = createdTime;
}
public LocalDateTime getUpdatedTime() {
return updatedTime;
}
public void setUpdatedTime(LocalDateTime updatedTime) {
this.updatedTime = updatedTime;
}
}