내원 이력 6종 — 125종 → 131종
OCM_FollowUp(bzDataInterface.vb:1028 — 지금 이후 취소 아닌 내원. 원문의 ROWNUM 은 ORDER BY 보다 먼저 걸려 임의 행이었다 — 인라인뷰 정렬로 "가장 가까운 미래 내원"에 고정), OCM_외출외박신청일/종료일 (:1883/:1936 — 오늘 포함 CowSlpOut='Y' 구간의 시작/끝. 0행이면 서버 현재시각이 나오는 레거시 폴백을 SQL NVL 로 그대로 옮겼다 — ㉛에서 12자 폴백 확인), OCM_최초내원일(:1988 Case Else — 이 쿼리는 원문부터 인라인뷰 정렬이 있어 결정적. KIMEYE 분기 미이식), OCM_초진일_발병일(:2040)·OCM_신환_초진일(:2138 — 진료과 앞 2자를 레거시는 GetCodInfDT 임의 행에서 뽑았지만 우리는 문맥의 진료 행에서). "지금/오늘"은 전부 서버 시각(SYSDATE) — 레거시 SystemDateTime 과 같은 의미이고 단말 시계에 좌우되지 않는다. - dotnet test 338/338 · --edit-smoke 실패 0 (이름 검사 131종) - --db-patient ①~㉝ 전건 통과 — ㉝ 신설: 재진 있는 차트로 실값 검증 - --db-render P062 md5 8d683835f5d81e7bb41c79071d6bf954 불변 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
4642439ffd
commit
ec47c98bdd
@@ -2347,9 +2347,14 @@ public static class DbSmoke
|
||||
+ $" · 급여세대주 {extra.HouseholderNameByInsurance(extraOwner, "0", "1").Length}자"
|
||||
+ (owner2 is null ? ""
|
||||
: $" · 건보세대주 {extra.HouseholderName(extraOwner, owner2.Value).Length}자"
|
||||
+ $" · 협력업체 {extra.Cooperator(owner2.Value).Length}자");
|
||||
+ $" · 협력업체 {extra.Cooperator(owner2.Value).Length}자")
|
||||
+ $" · FollowUp {extra.FollowUp(extraOwner).Length}자"
|
||||
+ $" · 최초내원 {extra.FirstVisit(extraOwner, "999912312359").Length}자"
|
||||
+ $" · 초진일 {extra.FirstVisitByDepartment(extraOwner, "999912312359", "00", false).Length}자"
|
||||
+ (owner2 is null ? ""
|
||||
: $" · 외출외박 {extra.LeaveOfAbsence(owner2.Value, false).Length}자");
|
||||
lines.Add($" 부가정보: {shapes} (값은 기록하지 않는다)");
|
||||
Check("㉛ 부가정보 7종 조회가 예외 없이 돈다", true, "");
|
||||
Check("㉛ 부가정보·내원이력 조회가 예외 없이 돈다", true, "");
|
||||
|
||||
// "돌지만 항상 0행"인 매칭 실수(RPAD·조인)를 가른다 —
|
||||
// 값이 있는 차트를 골라서 물으면 반드시 값이 나와야 한다.
|
||||
@@ -2367,11 +2372,28 @@ public static class DbSmoke
|
||||
extra.Nationality(natOwner).Length > 0,
|
||||
"RPAD 매칭이나 NATCOD 조인을 의심할 것");
|
||||
}
|
||||
|
||||
// 최초내원일도 같은 방식 — 재진(ComNfsTyp='2') 내원이 있는
|
||||
// 차트를 골라서 물으면 반드시 값이 나와야 한다.
|
||||
var revisitOwner = FirstText(conn,
|
||||
"SELECT TRIM(ComChtNum) FROM P_ComInf"
|
||||
+ " INNER JOIN P_CodInf ON ComNum = CodComNum"
|
||||
+ " WHERE ComAcpStt <> 'OC' AND ComNfsTyp = '2' AND ROWNUM = 1");
|
||||
if (revisitOwner.Length == 0)
|
||||
{
|
||||
lines.Add("SKIP ㉝ 최초내원일 값 — 재진 내원이 없어 판정 불가");
|
||||
}
|
||||
else
|
||||
{
|
||||
Check("㉝ 재진 내원이 있는 차트에서는 최초내원일이 나온다",
|
||||
extra.FirstVisit(revisitOwner, "999912312359").Length >= 8,
|
||||
"RPAD 매칭이나 P_CodInf 조인을 의심할 것");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Check("㉛ 부가정보 7종 조회가 예외 없이 돈다", false,
|
||||
Check("㉛ 부가정보·내원이력 조회가 예외 없이 돈다", false,
|
||||
$"{ex.GetType().Name}: {ex.Message.Split('\n')[0]}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,6 +155,12 @@ public sealed class PatientTagResolver : ITagValueResolver
|
||||
? $"{value[..4]}-{value[4..6]}-{value[6..8]} {value[8..10]}:{value[10..12]}"
|
||||
: string.Empty;
|
||||
|
||||
/// <summary>YYYYMMDDHHMM → "9999년99월99일 99시99분" (공백 3칸 — 레거시 포맷 문자열 그대로)</summary>
|
||||
private static string StampKorean(string value)
|
||||
=> value.Length >= 12
|
||||
? $"{value[..4]}년{value[4..6]}월{value[6..8]}일 {value[8..10]}시{value[10..12]}분"
|
||||
: string.Empty;
|
||||
|
||||
private readonly ITagValueResolver next;
|
||||
private readonly PatientContext context;
|
||||
|
||||
@@ -893,7 +899,9 @@ public sealed class PatientTagResolver : ITagValueResolver
|
||||
private TagValue? FromExtra(string tag)
|
||||
{
|
||||
if (tag is not ("PAT_실제생년월일" or "PAT_국적" or "PAT_장애등급" or "PAT_건보세대주명"
|
||||
or "PAT_건보_급여_세대주명" or "PAT_협력업체" or "PAT_보호자연락처"))
|
||||
or "PAT_건보_급여_세대주명" or "PAT_협력업체" or "PAT_보호자연락처"
|
||||
or "OCM_FollowUp" or "OCM_외출외박신청일" or "OCM_외출외박종료일"
|
||||
or "OCM_최초내원일" or "OCM_초진일_발병일" or "OCM_신환_초진일"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -976,8 +984,59 @@ public sealed class PatientTagResolver : ITagValueResolver
|
||||
? Wrap(store.Cooperator(m), "협력업체 코드가 없거나 코드표에 이름이 없습니다")
|
||||
: new TagValue(false, "이 내원의 내원번호를 읽지 못했습니다");
|
||||
}
|
||||
default:
|
||||
case "PAT_보호자연락처":
|
||||
return Wrap(store.GuardianPhone(chtNum), "부가정보에 보호자연락처가 없습니다");
|
||||
case "OCM_FollowUp":
|
||||
{
|
||||
// 지금보다 뒤의 내원이 없으면 레거시도 "" 다(:1055) — 사유로 말한다
|
||||
var next = store.FollowUp(chtNum);
|
||||
return next.Length >= 12
|
||||
? new TagValue(true, Stamp(next))
|
||||
: new TagValue(false, "지금 이후로 잡힌 내원이 없습니다");
|
||||
}
|
||||
case "OCM_외출외박신청일":
|
||||
case "OCM_외출외박종료일":
|
||||
{
|
||||
var comNum = PatientContext.Value(context.ComInf, "ComNum");
|
||||
if (!decimal.TryParse(comNum, out var m))
|
||||
{
|
||||
return new TagValue(false, "이 내원의 내원번호를 읽지 못했습니다");
|
||||
}
|
||||
// 기록이 없으면 서버 현재시각이 온다 — 레거시 폴백 그대로(:1924-1927)
|
||||
var moment = store.LeaveOfAbsence(m, endSide: tag == "OCM_외출외박종료일");
|
||||
return moment.Length >= 12
|
||||
? new TagValue(true, StampKorean(moment))
|
||||
: new TagValue(false, "외출·외박 일시를 만들지 못했습니다");
|
||||
}
|
||||
default:
|
||||
{
|
||||
// 최초내원일·초진일 계열 — 이 내원의 접수일시가 상한이다(레거시 :2001)
|
||||
var acpDtm = PatientContext.Value(context.ComInf, "ComAcpDtm");
|
||||
if (acpDtm.Length == 0)
|
||||
{
|
||||
return new TagValue(false, "이 내원의 접수일시를 읽지 못했습니다");
|
||||
}
|
||||
string first;
|
||||
if (tag == "OCM_최초내원일")
|
||||
{
|
||||
first = store.FirstVisit(chtNum, acpDtm);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 진료과 앞 2자는 레거시가 GetCodInfDT 임의 행에서 뽑았다(:2057) —
|
||||
// 우리는 문맥의 진료 행(결정 규칙 적용)에서 뽑는다
|
||||
var depCod = PatientContext.Value(context.CodInf, "CodDepCod");
|
||||
if (depCod.Length < 2)
|
||||
{
|
||||
return new TagValue(false, "이 내원의 진료과 코드를 읽지 못했습니다");
|
||||
}
|
||||
first = store.FirstVisitByDepartment(chtNum, acpDtm, depCod[..2],
|
||||
includeNew: tag == "OCM_신환_초진일");
|
||||
}
|
||||
return first.Length >= 8
|
||||
? new TagValue(true, $"{first[..4]}/{first[4..6]}/{first[6..8]}")
|
||||
: new TagValue(false, "조건에 맞는 이전 내원이 없습니다");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -1083,6 +1142,8 @@ public sealed class PatientTagResolver : ITagValueResolver
|
||||
"PAT_성별_남", "PAT_성별_여",
|
||||
"PAT_실제생년월일", "PAT_국적", "PAT_장애등급", "PAT_건보세대주명",
|
||||
"PAT_건보_급여_세대주명", "PAT_협력업체", "PAT_보호자연락처",
|
||||
"OCM_FollowUp", "OCM_외출외박신청일", "OCM_외출외박종료일",
|
||||
"OCM_최초내원일", "OCM_초진일_발병일", "OCM_신환_초진일",
|
||||
"PAT_우편번호", "PAT_도로명주소", "PAT_지번주소", "PAT_영문도로명주소",
|
||||
"OCM_담당의사", "OCM_담당의사_담당의사코드", "OCM_담당의사_연락처",
|
||||
"OCM_진료과", "ETC_요양기관명칭_병원명",
|
||||
|
||||
Reference in New Issue
Block a user