번식 능력 검사 리스트 및 보고서 수정
This commit is contained in:
@@ -9,6 +9,8 @@ import { CowModel } from '../cow/entities/cow.entity';
|
||||
import { FarmModel } from '../farm/entities/farm.entity';
|
||||
import { GenomeRequestModel } from './entities/genome-request.entity';
|
||||
import { GenomeTraitDetailModel } from './entities/genome-trait-detail.entity';
|
||||
import { MptModel } from '../mpt/entities/mpt.entity';
|
||||
import { GeneDetailModel } from '../gene/entities/gene-detail.entity';
|
||||
|
||||
/**
|
||||
* 낮을수록 좋은 형질 목록 (부호 반전 필요)
|
||||
@@ -139,6 +141,14 @@ export class GenomeService {
|
||||
// 농장 정보 Repository
|
||||
@InjectRepository(FarmModel)
|
||||
private readonly farmRepository: Repository<FarmModel>,
|
||||
|
||||
// 번식능력검사 Repository
|
||||
@InjectRepository(MptModel)
|
||||
private readonly mptRepository: Repository<MptModel>,
|
||||
|
||||
// 유전자검사 상세 Repository
|
||||
@InjectRepository(GeneDetailModel)
|
||||
private readonly geneDetailRepository: Repository<GeneDetailModel>,
|
||||
) { }
|
||||
|
||||
// ============================================
|
||||
@@ -359,7 +369,11 @@ export class GenomeService {
|
||||
}[];
|
||||
// 요약
|
||||
summary: {
|
||||
totalRequests: number;
|
||||
totalCows: number; // 검사 받은 전체 개체 수 (합집합, 중복 제외)
|
||||
genomeCowCount: number; // 유전체 분석 개체 수
|
||||
geneCowCount: number; // 유전자검사 개체 수
|
||||
mptCowCount: number; // 번식능력검사 개체 수
|
||||
totalRequests: number; // 유전체 의뢰 건수 (기존 호환성)
|
||||
analyzedCount: number;
|
||||
pendingCount: number;
|
||||
mismatchCount: number;
|
||||
@@ -729,21 +743,79 @@ export class GenomeService {
|
||||
const mismatchCount = requests.filter(r => r.chipSireName && r.chipSireName !== '일치').length;
|
||||
const pendingCount = totalRequests - analyzedCount - mismatchCount;
|
||||
|
||||
// 성별 체크 - 디버깅 강화
|
||||
// 실제 성별 값 분석
|
||||
const sexAnalysis = requests.map(r => ({
|
||||
cowId: r.cow?.cowId,
|
||||
cowSex: r.cow?.cowSex,
|
||||
hasCow: !!r.cow,
|
||||
}));
|
||||
// Step 5.1: 검사 유형별 개체 수 계산 (합집합, 중복 제외)
|
||||
// 농장 소유 개체의 cowId 목록 조회
|
||||
const farmCows = await this.cowRepository.find({
|
||||
where: { fkFarmNo: farmNo, delDt: IsNull() },
|
||||
select: ['cowId', 'cowSex'],
|
||||
});
|
||||
const farmCowIds = new Set(farmCows.map(c => c.cowId).filter(Boolean));
|
||||
const farmCowMap = new Map(farmCows.map(c => [c.cowId, c]));
|
||||
|
||||
// 성별 체크 (M/수/1 = 수컷, 그 외 모두 암컷으로 처리)
|
||||
const maleCount = requests.filter(r => {
|
||||
const sex = r.cow?.cowSex?.toUpperCase();
|
||||
return sex === 'M' || sex === '수' || sex === '1';
|
||||
}).length;
|
||||
// 수컷이 아니면 모두 암컷으로 처리 (null 포함)
|
||||
const femaleCount = requests.length - maleCount;
|
||||
// 각 검사별 cowId 조회 (병렬 처리) - genomeRequest도 포함 (리스트 페이지와 일치)
|
||||
const [genomeRequestCowIds, genomeCowIds, geneCowIds, mptCowIds] = await Promise.all([
|
||||
// 유전체 분석 의뢰가 있는 개체 (분석불가 포함)
|
||||
this.genomeRequestRepository
|
||||
.createQueryBuilder('request')
|
||||
.innerJoin('request.cow', 'cow')
|
||||
.select('DISTINCT cow.cowId', 'cowId')
|
||||
.where('request.delDt IS NULL')
|
||||
.getRawMany()
|
||||
.then(rows => rows.map((r: { cowId: string }) => r.cowId).filter(Boolean)),
|
||||
// 유전체 분석 개체 (형질 데이터 보유)
|
||||
this.genomeTraitDetailRepository
|
||||
.createQueryBuilder('trait')
|
||||
.select('DISTINCT trait.cowId', 'cowId')
|
||||
.where('trait.delDt IS NULL')
|
||||
.getRawMany()
|
||||
.then(rows => rows.map((r: { cowId: string }) => r.cowId).filter(Boolean)),
|
||||
// 유전자검사 개체
|
||||
this.geneDetailRepository
|
||||
.createQueryBuilder('gene')
|
||||
.select('DISTINCT gene.cowId', 'cowId')
|
||||
.where('gene.delDt IS NULL')
|
||||
.getRawMany()
|
||||
.then(rows => rows.map((r: { cowId: string }) => r.cowId).filter(Boolean)),
|
||||
// 번식능력검사 개체
|
||||
this.mptRepository
|
||||
.createQueryBuilder('mpt')
|
||||
.select('DISTINCT mpt.cowId', 'cowId')
|
||||
.where('mpt.delDt IS NULL')
|
||||
.getRawMany()
|
||||
.then(rows => rows.map((r: { cowId: string }) => r.cowId).filter(Boolean)),
|
||||
]);
|
||||
|
||||
// 농장 소유 개체만 필터링
|
||||
const farmGenomeRequestCowIds = genomeRequestCowIds.filter(id => farmCowIds.has(id));
|
||||
const farmGenomeCowIds = genomeCowIds.filter(id => farmCowIds.has(id));
|
||||
const farmGeneCowIds = geneCowIds.filter(id => farmCowIds.has(id));
|
||||
const farmMptCowIds = mptCowIds.filter(id => farmCowIds.has(id));
|
||||
|
||||
// 합집합 계산 (중복 제외) - genomeRequest 포함 (리스트 페이지와 일치)
|
||||
const allTestedCowIds = new Set([
|
||||
...farmGenomeRequestCowIds,
|
||||
...farmGenomeCowIds,
|
||||
...farmGeneCowIds,
|
||||
...farmMptCowIds,
|
||||
]);
|
||||
|
||||
const totalCows = allTestedCowIds.size;
|
||||
const genomeCowCount = farmGenomeCowIds.length;
|
||||
const geneCowCount = farmGeneCowIds.length;
|
||||
const mptCowCount = farmMptCowIds.length;
|
||||
|
||||
// 성별 체크 - 전체 검사 개체 기준 (M/수/1 = 수컷, 그 외 모두 암컷으로 처리)
|
||||
let maleCount = 0;
|
||||
let femaleCount = 0;
|
||||
for (const cowId of allTestedCowIds) {
|
||||
const cow = farmCowMap.get(cowId);
|
||||
const sex = cow?.cowSex?.toUpperCase();
|
||||
if (sex === 'M' || sex === '수' || sex === '1') {
|
||||
maleCount++;
|
||||
} else {
|
||||
femaleCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// Step 6: 검사 종류별 현황 (SNP, MS)
|
||||
const testTypeStats = {
|
||||
@@ -822,7 +894,11 @@ export class GenomeService {
|
||||
yearlyAvgEbv,
|
||||
requestHistory,
|
||||
summary: {
|
||||
totalRequests,
|
||||
totalCows, // 검사 받은 전체 개체 수 (합집합)
|
||||
genomeCowCount, // 유전체 분석 개체 수
|
||||
geneCowCount, // 유전자검사 개체 수
|
||||
mptCowCount, // 번식능력검사 개체 수
|
||||
totalRequests, // 유전체 의뢰 건수 (기존 호환성)
|
||||
analyzedCount,
|
||||
pendingCount,
|
||||
mismatchCount,
|
||||
|
||||
Reference in New Issue
Block a user