# EngineeringRequestController.java

    package cloud.wconnect.frontoffice.controller.engineeringrequest;

    import cloud.wconnect.commonlib.annotation.ApiId;
    import cloud.wconnect.commonlib.component.SessionContext;
    import cloud.wconnect.commonlib.cons.BaseErrorCodeEnum;
    import cloud.wconnect.commonlib.cons.CommonErrorI18nConstant;
    import cloud.wconnect.commonlib.cons.CommonFieldI18nConstant;
    import cloud.wconnect.commonlib.exception.BadRequestException;
    import cloud.wconnect.commonlib.exception.ForbiddenException;
    import cloud.wconnect.commonlib.pojo.dto.ListPagedDTO;
    import cloud.wconnect.commonlib.util.I18nMessageUtils;
    import cloud.wconnect.frontoffice.cons.engineeringrequest.EngineeringRequestCons;
    import cloud.wconnect.frontoffice.cons.engineeringrequest.EngineeringRequestStatusEnum;
    import cloud.wconnect.frontoffice.entity.engineeringrequest.*;
    import cloud.wconnect.frontoffice.pojo.bo.engineeringrequest.NotifyBodyBO;
    import cloud.wconnect.frontoffice.pojo.dto.engineeringrequest.EngineeringRequestCommentDTO;
    import cloud.wconnect.frontoffice.pojo.dto.engineeringrequest.EngineeringRequestDTO;
    import cloud.wconnect.frontoffice.pojo.dto.engineeringrequest.UpdateEngineeringRequestDTO;
    import cloud.wconnect.frontoffice.pojo.dto.engineeringrequest.UpdateEngineeringRequestStatusDTO;
    import cloud.wconnect.frontoffice.pojo.query.engineeringrequest.EngineeringRequestQuery;
    import cloud.wconnect.frontoffice.service.engineeringrequest.*;
    import cloud.wconnect.frontoffice.service.engineeringrequest.notify.EngineeringRequestNotifyService;
    import jakarta.validation.Valid;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;

    import java.util.Collections;
    import java.util.List;
    import java.util.Map;

    /**
     * <p>
     * 前端控制器
     * </p>
     *
     * @author yyt
     * @since 2023-05-10
     */
    @RestController
    @RequestMapping("/engineering-request")
    public class EngineeringRequestController {

        @Autowired
        private IEngineeringRequestService engineeringRequestService;
        @Autowired
        private IEngineeringRequestCommentService engineeringRequestCommentService;
        @Autowired
        private IEngineeringRequestLocationService engineeringRequestLocationService;
        @Autowired
        private IEngineeringRequestAreaService engineeringRequestAreaService;
        @Autowired
        private IEngineeringRequestItemService engineeringRequestItemService;
        @Autowired
        private IEngineeringRequestIssueService engineeringRequestIssueService;
        @Autowired
        private EngineeringRequestNotifyService engineeringRequestCreateOperation;
        @Autowired
        private EngineeringRequestNotifyService engineeringRequestUpdateOperation;
        @Autowired
        private EngineeringRequestNotifyService engineeringRequestAcceptOperation;
        @Autowired
        private  EngineeringRequestNotifyService engineeringRequestResolveOperation;
        @Autowired
        private SessionContext sessionContext;
        @Autowired
        private I18nMessageUtils i18nMessageUtils;

        /**
         * 检索列表
         *
         * @param query 查询条件
         * @return Engineering Request
         * @author yyt
         * @date 2023/3/29
         */
        @ApiId(212)
        @GetMapping
        public ListPagedDTO<EngineeringRequestDTO> listEngineeringRequest(@Valid EngineeringRequestQuery query) {
            return engineeringRequestService.listEngineeringRequestDTO(sessionContext.getPropertyId(query.getProperty()), query);
        }

        /**
         * 新增、编辑
         *
         * @param id                          Engineering Request Id
         * @param property                    资产标识
         * @param updateEngineeringRequestDTO Engineering Request 信息
         * @return {}
         * @author yyt
         * @date 2023/3/29
         */
        @ApiId(213)
        @PostMapping("/{id:\\d+}")
        public Map save(@PathVariable("id") int id, @RequestParam String property,
                                @Valid @RequestBody UpdateEngineeringRequestDTO updateEngineeringRequestDTO) {
            int propertyId = sessionContext.getPropertyId(property);

            checkSelectOption(updateEngineeringRequestDTO, propertyId);

            if (id == 0) {
                EngineeringRequest engineeringRequest = engineeringRequestService.save(propertyId, updateEngineeringRequestDTO, sessionContext.getLoginUserId());

                engineeringRequestCreateOperation.notify(new NotifyBodyBO(engineeringRequest.getId()));
            } else {
                EngineeringRequest engineeringRequest = engineeringRequestService.checkExist(id);

                checkPropertySame(engineeringRequest, propertyId);

                if (engineeringRequest.getTicketStatus() != EngineeringRequest.STATUS_OPEN) {
                    throw new BadRequestException(CommonErrorI18nConstant.SPECIFIC_STATE_CAN_OPERATE,
                            i18nMessageUtils.getErrorParamMapNeedTranslate(EngineeringRequestStatusEnum.OPEN.getI18nCode(), CommonFieldI18nConstant.EDIT),
                            BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "the status is not open and cannot be edited;id:" + id);
                }

                engineeringRequest = engineeringRequestService.update(engineeringRequest, updateEngineeringRequestDTO, sessionContext.getLoginUserId());

                engineeringRequestUpdateOperation.notify(new NotifyBodyBO(engineeringRequest.getId()));
            }

            return Collections.emptyMap();
        }

        /**
         * 校验下拉框选项
         *
         * @param updateEngineeringRequestDTO 选项信息
         * @param propertyId                  当前资产
         * @author yyt
         * @date 2023/5/11
         */
        private void checkSelectOption(UpdateEngineeringRequestDTO updateEngineeringRequestDTO, Integer propertyId) {
            EngineeringRequestLocation location = engineeringRequestLocationService.checkExist(updateEngineeringRequestDTO.getLocationId());
            if (!location.getPropertyId().equals(propertyId)) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(),
                        "the location does not belong to the current property;id:" + updateEngineeringRequestDTO.getLocationId()
                                + ",locationPropertyId:" + location.getPropertyId() + ",currentPropertyId:" + propertyId);
            }

            EngineeringRequestArea area = engineeringRequestAreaService.checkExist(location.getId(), updateEngineeringRequestDTO.getAreaId());
            if (!area.getPropertyId().equals(propertyId)) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(),
                        "the area does not belong to the current property;id:" + updateEngineeringRequestDTO.getAreaId()
                                + ",areaPropertyId:" + area.getPropertyId() + ",currentPropertyId:" + propertyId);
            }

            EngineeringRequestItem item = engineeringRequestItemService.checkExist(location.getId(), area.getId(), updateEngineeringRequestDTO.getItemId());
            if (!item.getPropertyId().equals(propertyId)) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(),
                        "the item does not belong to the current property;id:" + updateEngineeringRequestDTO.getItemId()
                                + ",itemPropertyId:" + item.getPropertyId() + ",currentPropertyId:" + propertyId);
            }

            EngineeringRequestIssue issue = engineeringRequestIssueService.checkExist(updateEngineeringRequestDTO.getIssueId());
            if (!issue.getPropertyId().equals(propertyId)) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(),
                        "the issue does not belong to the current property;id:" + updateEngineeringRequestDTO.getIssueId()
                                + ",issuePropertyId:" + issue.getPropertyId() + ",currentPropertyId:" + propertyId);
            }
        }

        /**
         * 校验 Engineering Request Property 与 参数 Property 一致
         *
         * @param engineeringRequest Engineering Request
         * @param paramPropertyId    参数 Property
         * @author yyt
         * @date 2023/3/29
         */
        public void checkPropertySame(EngineeringRequest engineeringRequest, int paramPropertyId) {
            if (engineeringRequest.getPropertyId() != paramPropertyId) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(), "the property id parameter is different from " +
                        "the property id of the engineeringRequest;propertyId:" + paramPropertyId +
                        ",engineeringRequestPropertyId:" + engineeringRequest.getPropertyId() + ",engineeringRequestId:" + engineeringRequest.getId());
            }
        }

        /**
         * 查看详情
         *
         * @param id       Engineering Request Id
         * @param property 资产标识
         * @return Engineering Request 信息
         * @author yyt
         * @date 2023/3/29
         */
        @ApiId(214)
        @GetMapping("/{id:\\d+}")
        public EngineeringRequestDTO getDetail(@PathVariable("id") int id, @RequestParam String property) {
            EngineeringRequest engineeringRequest = engineeringRequestService.checkExist(id);

            checkPropertySame(engineeringRequest, sessionContext.getPropertyId(property));

            return engineeringRequestService.getDetailDTO(engineeringRequest);
        }

        /**
         * 修改状态
         *
         * @param id              Engineering Request Id
         * @param property        资产标识
         * @param updateStatusDTO 修改状态
         * @return {}
         * @author yyt
         * @date 2023/3/29
         */
        @ApiId(215)
        @PutMapping("/{id:\\d+}/status")
        public Map updateStatus(@PathVariable("id") int id, @RequestParam String property,
                                @Valid @RequestBody UpdateEngineeringRequestStatusDTO updateStatusDTO) {
            EngineeringRequest engineeringRequest = engineeringRequestService.checkExist(id);

            checkPropertySame(engineeringRequest, sessionContext.getPropertyId(property));

            engineeringRequest = engineeringRequestService.updateStatus(engineeringRequest, updateStatusDTO, sessionContext.getLoginUserId());

            if (updateStatusDTO.getNewStatus() == EngineeringRequest.STATUS_RESOLVE) {
                engineeringRequestResolveOperation.notify(new NotifyBodyBO(engineeringRequest.getId()));
            } else {
                engineeringRequestAcceptOperation.notify(new NotifyBodyBO(engineeringRequest.getId()));
            }

            return Collections.emptyMap();
        }

        /**
         * 获取备注列表
         *
         * @param id       Engineering Request Id
         * @param property 资产标识
         * @return 备注列表
         * @author yyt
         * @date 2023/3/30
         */
        @ApiId(216)
        @GetMapping("/{id:\\d+}/comment")
        public List<EngineeringRequestCommentDTO> listComment(@PathVariable("id") int id, @RequestParam String property) {
            EngineeringRequest engineeringRequest = engineeringRequestService.checkExist(id);

            checkPropertySame(engineeringRequest, sessionContext.getPropertyId(property));

            return engineeringRequestCommentService.listCommentDTO(sessionContext.getTenantSymbolBO().getId(), id);
        }

        /**
         * 添加备注
         *
         * @param id         Engineering Request Id
         * @param property   资产标识
         * @param commentDTO 备注信息
         * @return {}
         * @author yyt
         * @date 2023/3/30
         */
        @ApiId(217)
        @PostMapping("/{id:\\d+}/comment")
        public Map saveComment(@PathVariable("id") int id, @RequestParam String property,
                               @Valid @RequestBody EngineeringRequestCommentDTO commentDTO) {
            EngineeringRequest engineeringRequest = engineeringRequestService.checkExist(id);

            int propertyId = sessionContext.getPropertyId(property);
            checkPropertySame(engineeringRequest, propertyId);

            engineeringRequestCommentService.saveComment(id, propertyId, commentDTO, sessionContext.getLoginUserId());

            return Collections.emptyMap();
        }

        /**
         * 删除备注
         *
         * @param id       Engineering Request Id
         * @param cid      备注 id
         * @param property 资产标识
         * @return {}
         * @author yyt
         * @date 2023/3/30
         */
        @ApiId(218)
        @DeleteMapping("/{id:\\d+}/comment/{cid:\\d+}")
        public Map deleteComment(@PathVariable("id") int id, @PathVariable("cid") int cid, @RequestParam String property) {
            EngineeringRequest engineeringRequest = engineeringRequestService.checkExist(id);

            int propertyId = sessionContext.getPropertyId(property);
            checkPropertySame(engineeringRequest, propertyId);

            EngineeringRequestComment comment = engineeringRequestCommentService.checkExist(id, cid);
            if (comment.getCreateId() != sessionContext.getLoginUserId()) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(), "The comment is not created by the current login user;"
                        + "commentId: " + comment.getId() + ",commentCreateUserId:" + comment.getCreateId()
                        + ",loginUserId:" + sessionContext.getLoginUserId());
            }
            if (!comment.getPropertyId().equals(propertyId)) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(),
                        "the property id parameter is different from the property id of the engineeringRequestComment;" +
                                "propertyId:" + propertyId + ",engineeringRequestCommentPropertyId:" + comment.getPropertyId() +
                                ",engineeringRequestId:" + engineeringRequest.getId() + ",engineeringRequestCommentId:" + comment.getId());
            }
            if (comment.getCommentType() == EngineeringRequestComment.TYPE_REQUEST_ATTACHMENT) {
                throw new BadRequestException(EngineeringRequestCons.ENGINEERING_REQUEST_ATTACHMENT_NOT_SUPPORT_DELETE,
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "The engineeringRequest attachment cannot be deleted;" +
                        "engineeringRequestId:" + id + ",engineeringRequestCommentId:" + cid);
            }

            engineeringRequestCommentService.delete(comment);

            return Collections.emptyMap();
        }

    }