Загрузка данных


@Override
    @Transactional
    public QuestionOutput create(QuestionRequest questionRequest) {
        try {
            log.info("Start creating SMB question with name: {}. Parent id: {}",
                    questionRequest.getName(),
                    questionRequest.getParentId()
            );

            securityService.setContextByTechUser();

            QuestionCreditcom question = questionCreditcomService.create(ExternalQuestionMapper.map(questionRequest));

            log.info("Created question with id: {}", question.getId());

            QuestionResponse questionResponse = dataProcessService.map(question, QuestionResponse.class);
            questionResponse.setQuestionId(question.getId());
            questionResponse.setIsStrict810(question.isStrict810());
            questionResponse.setCallbackUrl(
                    questionCreditcomUtils.getCallbackUrl(question.getType(), question.getId(), question.getStatus()));

            List<FullMember> members = new ArrayList<>();

            if (!CollectionUtils.isEmpty(questionRequest.getMembers())) {
                log.info("Start adding members to question...");
                List<FullMemberResponse> fullMemberResponses =
                        memberEnricher.toResponseList(memberService.findAllMembersByQuestionId(question.getId()));
                members.addAll(
                        fullMemberResponses.stream()
                                .map(fullMemberResponse ->
                                        FullMember.builder()
                                                .questionId(question.getId())
                                                .memberId(fullMemberResponse.getMemberId())
                                                .role(fullMemberResponse.getRole())
                                                .userName(fullMemberResponse.getUserName())
                                                .build())
                                .toList()
                );
                log.info("Added question members: {}", members);
            }

            List<QuestionFileDto> questionFileDtoList = new ArrayList<>();

            if (!CollectionUtils.isEmpty(questionRequest.getDocuments())) {

                log.info("Start adding files to question...");

                Set<UUID> cxkIds = questionRequest.getDocuments().stream()
                        .map(QuestionRequest.Document::getId)
                        .filter(Objects::nonNull)
                        .collect(Collectors.toSet());

                var collectionFileInfoResponse = fileServiceApiClient.getFileInfoByCxkIds(cxkIds).getCollection();
                var fileInfoList = buildFileInfoList(collectionFileInfoResponse, questionRequest.getDocuments());

                List<QuestionFileShortDto> questionFileDtos =
                        fileInfoList.stream()
                                .map(x -> toQuestionFileDto(x, question.getId()))
                                .toList();

                if (!CollectionUtils.isEmpty(questionFileDtos)) {
                    questionFileDtoList.addAll(questionFileService.addQuestionFiles(questionFileDtos));
                    log.info("Added question files: {}", questionFileDtoList);
                } else {
                    log.info("No files was found");
                }
            }

            QuestionOutput questionOutput = ExternalQuestionMapper.map(questionResponse, members, questionFileDtoList);

            log.info("Successfully created SMB question with id: {}", question.getId());

            return questionOutput;
        } catch (Exception e) {
            log.error("Error while create SMB question: {}", e.getMessage());
            throw e;
        }
    }

    private List<FileInfo> buildFileInfoList(List<FileInfoResponse> fileInfoResponses, List<QuestionRequest.Document> documents) {
        var employeeExternalIds = documents.stream()
                .map(QuestionRequest.Document::getDocumentAuthorExternalId)
                .filter(id -> id != null && !id.isBlank())
                .collect(Collectors.toSet());

        Collection<EmployeeDto> employees = employeeExternalIds.isEmpty()
                ? List.of()
                : employeeApiClient.getByExternalIds(employeeExternalIds);

        var employeesMap = employees.stream()
                .collect(Collectors.toMap(
                        EmployeeDto::getExternalId,
                        EmployeeDto::getUserName,
                        (a, b) -> a));

        var missingExternalIds = employeeExternalIds.stream()
                .filter(id -> !employeesMap.containsKey(id))
                .collect(Collectors.toSet());

        if (!missingExternalIds.isEmpty()) {
            log.warn("Employees not found for {} of {} externalIds: {}", missingExternalIds.size(), employeeExternalIds.size(), missingExternalIds);
        }

        var defaultInitiatorName = securityService.getCurrentUsername();

        return fileInfoResponses.stream()
                .map(f -> documents.stream()
                        .filter(d -> d.getId().equals(f.getId()))
                        .findFirst()
                        .map(d -> {
                            var initiator = (d.getDocumentAuthorExternalId() == null || d.getDocumentAuthorExternalId().isBlank())
                                    ? defaultInitiatorName
                                    : employeesMap.getOrDefault(d.getDocumentAuthorExternalId(), defaultInitiatorName);
                            return new FileInfo(
                                    f,
                                    d.getDecisionCategoryType(),
                                    initiator,
                                    d.getDocumentCreationTime());
                        })
                        .orElse(null))
                .filter(Objects::nonNull)
                .toList();
    }

    private QuestionFileShortDto toQuestionFileDto(FileInfo fileInfo, UUID questionId) {
        return QuestionFileShortDto.builder()
                .id(fileInfo.fileInfoResponse.getId())
                .questionId(questionId)
                .cxkId(String.valueOf(fileInfo.fileInfoResponse.getId()))
                .fileName(fileInfo.fileInfoResponse.getFileName())
                .documentUrl(String.format(FILE_BASE_URL, fileInfo.fileInfoResponse.getId()))
                .documentType(fileInfo.decisionCategoryType == null ? DOCUMENT_TYPE : fileInfo.decisionCategoryType)
                .documentTypeName(DOCUMENT_TYPE_NAME)
                .initiator(fileInfo.initiator())
                .addDate(fileInfo.addDate)
                .size(String.valueOf(fileInfo.fileInfoResponse.getSize()))
                .build();
    }

    record FileInfo(FileInfoResponse fileInfoResponse,
                     String decisionCategoryType,
                     String initiator,
                     OffsetDateTime addDate
    ) {
    }