File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
package kr.itn.itnhub.process;
import kr.itn.itnhub.org.OrgNotFoundException;
import kr.itn.itnhub.org.OrganizationMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;
import java.io.InputStream;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Service
public class ProcessImportService {
private final ProcessParser parser;
private final ProcessItemMapper mapper;
private final OrganizationMapper orgMapper;
private final kr.itn.itnhub.stage.StageService stageService;
private final kr.itn.itnhub.code.CodeService codeService;
private final TransactionTemplate transactionTemplate;
public ProcessImportService(ProcessParser parser, ProcessItemMapper mapper, OrganizationMapper orgMapper,
kr.itn.itnhub.stage.StageService stageService,
kr.itn.itnhub.code.CodeService codeService,
PlatformTransactionManager transactionManager) {
this.parser = parser;
this.mapper = mapper;
this.orgMapper = orgMapper;
this.stageService = stageService;
this.codeService = codeService;
this.transactionTemplate = new TransactionTemplate(transactionManager);
}
/** 공공누리 유형의 옛 표기를 표준 표기로 맞춘다(제4유형 → 4유형). */
private String canonicalKogl(String value) {
return codeService.canonical(kr.itn.itnhub.code.Codes.KOGL_TYPE, value);
}
/**
* 엑셀 파싱은 DB와 무관하므로 트랜잭션 밖에서 수행한다(ReviewImportService와 동일한 이유).
*/
public ProcessImportReport importFile(Long orgId, InputStream xlsx) {
if (orgMapper.findById(orgId) == null) {
throw new OrgNotFoundException("기관을 찾을 수 없습니다: " + orgId);
}
List<ProcessRow> rows = parser.parse(xlsx);
ProcessImportReport report = transactionTemplate.execute(status -> importRows(orgId, rows));
// 요구사항 [18]: 권리처리 자료가 올라오면 ⑧법률검토(권리처리)로 저절로 넘어간다.
// 이미 그보다 앞서 있으면 아무 일도 하지 않는다.
if (report != null && report.total() > 0) {
stageService.autoAdvance(orgId, kr.itn.itnhub.stage.AutoStage.PROCESS_STARTED,
kr.itn.itnhub.stage.AutoStage.REASON_PROCESS_STARTED);
}
return report;
}
private ProcessImportReport importRows(Long orgId, List<ProcessRow> rows) {
// 이미 DB에 있는 순번 + 이번 파일에서 먼저 처리된 순번을 모두 "이미 존재함"으로 취급한다
// (ReviewImportService.importRows와 동일한 관례).
Set<Integer> seen = new HashSet<>(mapper.findSeqsByOrg(orgId));
int created = 0;
int updated = 0;
for (ProcessRow row : rows) {
if (seen.add(row.seq())) {
created++;
} else {
updated++;
}
mapper.upsertFromFile(toProcessItem(orgId, row));
}
return new ProcessImportReport(created, updated, rows.size());
}
private ProcessItem toProcessItem(Long orgId, ProcessRow row) {
ProcessItem item = new ProcessItem();
item.setOrgId(orgId);
item.setSeq(row.seq());
item.setSiteName(row.siteName());
item.setCategory(row.category());
item.setBoardName(row.boardName());
item.setPostTitle(row.postTitle());
item.setUrl(row.url());
item.setDescription(row.description());
item.setHasAttachment(row.hasAttachment());
// 옛 표기(제4유형)로 적혀 온 값은 표준 표기(4유형)로 맞춰 넣는다.
item.setPriorKoglType(canonicalKogl(row.priorKoglType()));
item.setContractDocs(row.contractDocs());
item.setProducedDate(row.producedDate());
item.setPublishedDate(row.publishedDate());
item.setReviewMajor(row.reviewMajor());
item.setReviewMinor(row.reviewMinor());
item.setReviewResult(row.reviewResult());
item.setReviewKoglType(canonicalKogl(row.reviewKoglType()));
item.setReviewAiType(row.reviewAiType());
item.setReviewOpinion(row.reviewOpinion());
item.setReviewNote(row.reviewNote());
item.setPriorEvidence(row.priorEvidence());
item.setJudgedKoglType(canonicalKogl(row.judgedKoglType()));
item.setJudgedAiType(row.judgedAiType());
item.setFinalOpinion(row.finalOpinion());
item.setJudgmentBasis(row.judgmentBasis());
item.setProcessStatus(row.processStatus());
return item;
}
}