진단서 의사·수술일자·외래실진료일 16종 — 193종 → 209종 (조사 라운드 6)
진단서 계열 8종(bzDataInterface.vb:4380-4845): 로그인 사용자가 의사(UidDtrYon='Y')면 로그인 사용자의 값, 아니면 담당의의 값 — 시점·기준일(입원 CodEndDtm·외래 접수일)이 담당의 프리페치와 같은 판정이라 그 행을 재사용한다. 의사명(UidNam)·명_외래(입원이면 조회 없이 빈)·영문(UidEngNam)·면허(UidLicNum)·전문의(UidSpcLic)· 세부전문의(UidDtlSpcLic)·전문과목(개원일 2022-07-01 분기, TYRCH 미이식)·청구진료과목_로그인(DepBilCod→BDPTBL, 원문의 같은 쿼리 2회 실행은 1회로). 로그인 행에 영문명·세부전문의번호 컬럼 2개 추가. 값 5종: OCM_당뇨식칼로리_List(:3569 — 원문부터 결정적), OCM_수술일자(:2977 Case Else — 첫 수술 OprKey ASC; PURME·BSGH· HIMCHAN·GJHNSS 분기 미이식), OCM_수술일자_마지막수술(:2999), OCM_외래실진료일/_과목별(:1217/:1503 — 신환 첫 접수(폴백 전체 첫 접수)~마지막 접수 구간의 과 매칭 접수일 전부 "YYYY/MM/DD" ", " 결합. 같은 날 중복 출력도 원문 그대로. 본체 종료일 쿼리의 문자열 연결은 같은 값이라 바인드로 정상화). 사유 완결 3종: OCM_외래실진료일수(:1645 — 차트번호 자리에 시작일 바인드 + 없는 컬럼(OcmAcpDtm) 정렬, 상시 ORA-00904→빈 값인 레거시 결함), ETC_승인의사(:3892 — EmrKey 의존, 미리보기 부재), OCM_수술소독간호사(:3028 — PURME 전용, 그 외 병원은 빈 SQL 실행). - dotnet test 338/338 · --edit-smoke 실패 0 (이름 검사 209종) - --db-patient ①~㉟ 전건 통과 (㉟ 4종 추가 — 청구과목 실값 4자) - --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
4e6e086ece
commit
7dcc4c2e48
@@ -526,6 +526,94 @@ public sealed class PatientExtraStore
|
||||
+ " WHERE CodComNum = :m AND CodMtiSeq = '0' ORDER BY CodStrDtm",
|
||||
("m", comNum));
|
||||
|
||||
/// <summary>
|
||||
/// 청구 진료과목 이름(OCM_진단서청구진료과목_로그인, :4790) — 진료과의 청구코드
|
||||
/// (DepBilCod)를 코드표(BDPTBL)로 푼다. 기준일은 오늘(원문 SystemDate).
|
||||
/// 원문 Rows(0) 무가드 — 한 행으로 고정한다.
|
||||
/// </summary>
|
||||
public string BillingDepartmentName(string depCod)
|
||||
=> depCod.Trim().Length == 0 ? string.Empty
|
||||
: Scalar(
|
||||
"SELECT v FROM (SELECT DtlCodNam v FROM M_DepMst"
|
||||
+ " INNER JOIN M_DtlMst ON DepBilCod = DtlCod AND DtlTblCod = 'BDPTBL'"
|
||||
+ " AND TO_CHAR(SYSDATE, 'YYYYMMDD') BETWEEN DtlStrDte AND DtlExpDte"
|
||||
+ " WHERE TRIM(DepCod) = :d"
|
||||
+ " AND TO_CHAR(SYSDATE, 'YYYYMMDD') BETWEEN DepStrDte AND DepEndDte)"
|
||||
+ " WHERE ROWNUM = 1",
|
||||
("d", depCod.Trim()));
|
||||
|
||||
/// <summary>
|
||||
/// 당뇨식 칼로리(OCM_당뇨식칼로리_List, :3569) — 당뇨식 중 최신 식이일의 칼로리 1건.
|
||||
/// 원문부터 인라인뷰 정렬 + ROWNUM 이라 결정적이다(식이일 동률만 모호).
|
||||
/// </summary>
|
||||
public string DiabetesMealCalorie(string chtNum)
|
||||
=> Scalar(
|
||||
"SELECT ImlCal FROM (SELECT ImlCal FROM O_ImlInf"
|
||||
+ " INNER JOIN P_ComInf ON ComNum = ImlComNum AND ComChtNum = RPAD(:c, 10)"
|
||||
+ " INNER JOIN M_MgdMst ON MgdCod = ImlMgdCod"
|
||||
+ " WHERE MgdKorNam LIKE '%당뇨%' AND TO_NUMBER(ImlCal) > 0"
|
||||
+ " ORDER BY ImlDte DESC) WHERE ROWNUM = 1",
|
||||
("c", chtNum));
|
||||
|
||||
/// <summary>
|
||||
/// 수술 신청의 수술일자(OCM_수술일자 Case Else :2977 · OCM_수술일자_마지막수술 :2999) —
|
||||
/// 확정(OprStt='E') 수술의 OprDte. 본체는 첫 수술(OprKey ASC), 마지막수술은 최신
|
||||
/// (OprKey DESC). PURME(마취 오더)·BSGH/HIMCHAN/GJHNSS(DESC 뒤집기) 분기는 미이식.
|
||||
/// </summary>
|
||||
public string SurgeryDate(decimal comNum, bool latestFirst)
|
||||
=> Scalar(
|
||||
"SELECT v FROM (SELECT OprDte v FROM S_OprInf"
|
||||
+ " WHERE OprComNum = :m AND OprStt = 'E'"
|
||||
+ $" ORDER BY OprKey {(latestFirst ? "DESC" : "ASC")}) WHERE ROWNUM = 1",
|
||||
("m", comNum));
|
||||
|
||||
/// <summary>
|
||||
/// 외래 실진료일 목록(OCM_외래실진료일 :1217 · _과목별 :1503) — 신환('1') 첫 접수
|
||||
/// (없으면 전체 첫 접수)부터 마지막 접수까지, 지정 진료과의 접수일시 전부(시간순).
|
||||
/// exactDepartment=false 면 과 앞 2자 매칭(본체), true 면 전체 코드 일치(과목별).
|
||||
/// 원문 세 선행 쿼리 모두 인라인뷰 정렬 + ROWNUM 이라 결정적이다.
|
||||
/// 본체 원문의 종료일 쿼리는 차트번호를 문자열 연결로 넣지만 값이 같아 바인드로 정상화했다.
|
||||
/// </summary>
|
||||
public IReadOnlyList<string> OutpatientVisitDays(string chtNum, string acpDtm, string depCod, bool exactDepartment)
|
||||
{
|
||||
var first = Scalar(
|
||||
"SELECT v FROM (SELECT ComAcpDtm v FROM P_ComInf"
|
||||
+ " WHERE ComChtNum = RPAD(:c, 10) AND ComAcpDtm <= :a"
|
||||
+ " AND ComAcpStt <> 'OC' AND ComNfsTyp = '1'"
|
||||
+ " ORDER BY ComAcpDtm) WHERE ROWNUM = 1",
|
||||
("c", chtNum), ("a", acpDtm));
|
||||
if (first.Length < 8)
|
||||
{
|
||||
first = Scalar(
|
||||
"SELECT v FROM (SELECT ComAcpDtm v FROM P_ComInf"
|
||||
+ " WHERE ComChtNum = RPAD(:c, 10) AND ComAcpStt <> 'OC'"
|
||||
+ " ORDER BY ComAcpDtm ASC) WHERE ROWNUM = 1",
|
||||
("c", chtNum));
|
||||
}
|
||||
if (first.Length < 8)
|
||||
{
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
var last = Scalar(
|
||||
"SELECT v FROM (SELECT ComAcpDtm v FROM P_ComInf"
|
||||
+ " WHERE ComChtNum = RPAD(:c, 10) AND ComAcpStt <> 'OC'"
|
||||
+ " ORDER BY ComAcpDtm DESC) WHERE ROWNUM = 1",
|
||||
("c", chtNum));
|
||||
var depFilter = exactDepartment
|
||||
? " AND CodDepCod = :p" : " AND SUBSTR(CodDepCod, 1, 2) = :p";
|
||||
return Rows(
|
||||
"SELECT ComAcpDtm FROM P_ComInf"
|
||||
+ " INNER JOIN P_CodInf ON ComNum = CodComNum"
|
||||
+ " WHERE ComChtNum = RPAD(:c, 10)"
|
||||
+ " AND ComAcpDtm >= :s || '0000' AND ComAcpDtm <= :e || '9999'"
|
||||
+ depFilter + " AND ComAcpStt <> 'OC' ORDER BY ComAcpDtm",
|
||||
("c", chtNum), ("s", first[..8]), ("e", last.Length >= 8 ? last[..8] : string.Empty),
|
||||
("p", depCod))
|
||||
.Select(r => r.TryGetValue("ComAcpDtm", out var v) ? v : string.Empty)
|
||||
.Where(v => v.Length >= 8)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>스칼라 1칸 — 0행이거나 NULL 이면 빈 문자열. 잔여 공백은 걷는다(문맥 행과 같은 규칙)</summary>
|
||||
private string Scalar(string sql, params (string Name, object Value)[] binds)
|
||||
{
|
||||
|
||||
@@ -21,7 +21,11 @@ public sealed record HisUser(
|
||||
/// <summary>직종명(M_DtsMst JOBCOD 의 DtsCodNam) — ETC_로그인_직종</summary>
|
||||
string JobName = "",
|
||||
/// <summary>부서 전화번호(M_DepMst.DepTelNum) — ETC_접속유저_부서번호(이름과 달리 전화번호다)</summary>
|
||||
string DepPhone = "")
|
||||
string DepPhone = "",
|
||||
/// <summary>영문 이름(UidEngNam) — 진단서의사_영문의 로그인 의사 갈래</summary>
|
||||
string EnglishName = "",
|
||||
/// <summary>세부전문의번호(UidDtlSpcLic) — 진단서의사세부전문의번호</summary>
|
||||
string DetailSpecialistNumber = "")
|
||||
{
|
||||
/// <summary>미인증 세션(인자 없이 단독 실행) — DB 쓰기가 차단된다</summary>
|
||||
public static readonly HisUser Unknown = new(string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty);
|
||||
@@ -81,7 +85,7 @@ public sealed class UserContextStore
|
||||
" NVL(u.UidHspCod,' '), NVL(h.HspInsNam,' '), " +
|
||||
" NVL(u.UidDtrYon,' '), NVL(d.DepOfcNam,' '), " +
|
||||
" NVL(u.UidLicNum,' '), NVL(u.UidSpcLic,' '), NVL(j.DtsCodNam,' '), " +
|
||||
" NVL(d.DepTelNum,' ') " +
|
||||
" NVL(d.DepTelNum,' '), NVL(u.UidEngNam,' '), NVL(u.UidDtlSpcLic,' ') " +
|
||||
"FROM M_UidMst u " +
|
||||
"LEFT JOIN M_DepMst d ON d.DepCod = u.UidDepCod " +
|
||||
" AND TO_CHAR(SYSDATE,'YYYYMMDD') BETWEEN d.DepStrDte AND d.DepEndDte " +
|
||||
@@ -105,7 +109,7 @@ public sealed class UserContextStore
|
||||
reader.GetString(4).Trim(), reader.GetString(5).Trim(),
|
||||
reader.GetString(6).Trim(), reader.GetString(7).Trim(),
|
||||
reader.GetString(8).Trim(), reader.GetString(9).Trim(), reader.GetString(10).Trim(),
|
||||
reader.GetString(11).Trim());
|
||||
reader.GetString(11).Trim(), reader.GetString(12).Trim(), reader.GetString(13).Trim());
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user