유형·수납·진료기간·응급증상·전과내역 8종 — 185종 → 193종
OCM_계산유형(bzDataInterface.vb:5133 — 문맥 자격의 보험·계산 코드로
M_CalMst.CalNam), OCM_보험유형(:5186 — M_InsMst.InsNam),
OCM_수납일시(:5287 — 자격의 수납청구→수납 갱신일시. 원문 두 쿼리 다
비결정 Rows(0) — 최신 청구의 최신 수납으로 고정, 한 왕복으로 접음),
OCM_진료기간(:2236 — SRCH 갈래: 퇴원이면 접수~퇴원, 재원이면 최신
퇴원약 오더→퇴원예정→오늘 순. 외래: 최초 접수~최신 접수/오늘.
HANKOOK·SRH·GUPOSS 분기 미이식), OCM_진료기간_진료과(:2575 — 입원만
값. 외래는 두 번째 쿼리의 진료과 바인드 미등록(레거시 결함, :2644)으로
상시 ORA-01008→빈 값 — 사유로 완결), OCM_응급증상여부_YES/NO
(:12748/:12830 — 응급의료관리료 오더의 산정 여부. 코드 목록은
GetDtlMst("EMGEMGCOD") 그대로 + 0건이면 하드코딩 6종 폴백.
행이 없으면 레거시 $NoCheck$ — 체크 상태를 정하지 않는다.
SJRCH 분기 미이식), OCM_전과내역(:1103 — 과명+공백7+구간, CRLF 결합.
과 조인이 의사 조인에 종속되는 원문 모양 유지).
체크류 렌더 보완: 값을 못 만든 태그(사유)는 체크박스·라디오의 컨트롤을
그대로 둔다 — 레거시도 SetValue 를 건너뛴다. 라벨에 사유를 쓰면
"남 ☑" 이 "[태그 — 사유] ☑" 가 되어 서식이 깨진다.
- dotnet test 338/338 · --edit-smoke 실패 0 (이름 검사 193종)
- --db-patient ①~㉟ 전건 통과 (㉟ 에 7종 추가 — 보험유형 실값 4자,
응급 쿼리의 ORDER BY ROWID 모호성은 OdrKey 타이브레이크로 수정)
- --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
7bae9b9057
commit
4e6e086ece
@@ -385,6 +385,147 @@ public sealed class PatientExtraStore
|
||||
+ " WHERE ComNum = :m ORDER BY CowStrDtm ASC) WHERE ROWNUM = 1",
|
||||
("m", comNum));
|
||||
|
||||
/// <summary>
|
||||
/// 계산유형 이름(OCM_계산유형, :5133) — 자격의 보험·계산 코드로 M_CalMst.CalNam.
|
||||
/// 원문 Rows(0) 에 ORDER BY 가 없다 — 시작일 최신 행으로 고정한다.
|
||||
/// </summary>
|
||||
public string CalculationTypeName(string insCod, string calCod, string strDte)
|
||||
=> Scalar(
|
||||
"SELECT v FROM (SELECT CalNam v FROM M_CalMst"
|
||||
+ " WHERE CalInsCod = :i AND CalCod = :l AND :d BETWEEN CalStrDte AND CalEndDte"
|
||||
+ " ORDER BY CalStrDte DESC) WHERE ROWNUM = 1",
|
||||
("i", insCod), ("l", calCod), ("d", strDte));
|
||||
|
||||
/// <summary>보험유형 이름(OCM_보험유형, :5186) — M_InsMst.InsNam. 같은 규칙으로 고정</summary>
|
||||
public string InsuranceTypeName(string insCod, string strDte)
|
||||
=> Scalar(
|
||||
"SELECT v FROM (SELECT InsNam v FROM M_InsMst"
|
||||
+ " WHERE InsCod = :i AND :d BETWEEN InsStrDte AND InsEndDte"
|
||||
+ " ORDER BY InsStrDte DESC) WHERE ROWNUM = 1",
|
||||
("i", insCod), ("d", strDte));
|
||||
|
||||
/// <summary>
|
||||
/// 수납일시(OCM_수납일시, :5287) — 자격에 걸린 수납청구(P_RblInf, RblCalNxt=0)의
|
||||
/// 수납(P_RcpInf) 갱신일시 12자리. 원문은 두 쿼리 모두 ORDER BY 없는 Rows(0) —
|
||||
/// 청구·수납 다건이면 임의였다. 최신 청구의 최신 수납으로 고정하고 한 왕복으로 접었다.
|
||||
/// </summary>
|
||||
public string ReceiptStamp(decimal comNum, string mtiSeq, string strDte)
|
||||
=> Scalar(
|
||||
"SELECT v FROM (SELECT RcpUpdDtf v FROM P_RcpInf WHERE RcpRblNum IN ("
|
||||
+ " SELECT n FROM (SELECT RblNum n FROM P_RblInf"
|
||||
+ " WHERE RblComNum = :m AND RblMtiSeq = :s AND RblStrDte = :d AND RblCalNxt = 0"
|
||||
+ " ORDER BY RblNum DESC) WHERE ROWNUM = 1)"
|
||||
+ " ORDER BY RcpUpdDtf DESC) WHERE ROWNUM = 1",
|
||||
("m", comNum), ("s", mtiSeq), ("d", strDte));
|
||||
|
||||
/// <summary>
|
||||
/// 최신 퇴원약 오더 일시(OCM_진료기간 SRCH 갈래, :2299-2318) — 인라인뷰 정렬이
|
||||
/// 원문부터 있어 결정적이다. 필터(처방의약·숨김 제외 등)는 원문 그대로.
|
||||
/// </summary>
|
||||
public string DischargeMedicationOrderDate(decimal comNum)
|
||||
=> Scalar(
|
||||
"SELECT v FROM (SELECT OdrDtm v FROM O_OdrInf"
|
||||
+ " WHERE OdrComNum = :m AND OdrStt = 'OE'"
|
||||
+ " AND (OdrDscMed IS NOT NULL AND OdrDscMed <> ' ')"
|
||||
+ " AND (OdrHidden IS NULL OR OdrHidden <> 1)"
|
||||
+ " AND OdrGrpSub = 0"
|
||||
+ " AND (OdrAutCod IS NULL OR OdrAutCod = '-')"
|
||||
+ " AND (OdrSimEdt IS NULL OR OdrSimEdt NOT IN ('I','E'))"
|
||||
+ " ORDER BY OdrDtm DESC) WHERE ROWNUM = 1",
|
||||
("m", comNum));
|
||||
|
||||
/// <summary>
|
||||
/// 외래 진료기간 시작(OCM_진료기간 외래 갈래, :2325-2345) — 이 내원 이하의 취소 아닌
|
||||
/// 최초 접수일시. OCM_최초내원일과 달리 진료행 조인·재진 필터가 없다(원문 그대로 —
|
||||
/// ComNfsTyp='N' 조건은 주석 처리돼 있어 옮기지 않는다).
|
||||
/// </summary>
|
||||
public string TreatmentPeriodStart(string chtNum, string acpDtm)
|
||||
=> Scalar(
|
||||
"SELECT v FROM (SELECT ComAcpDtm v FROM P_ComInf"
|
||||
+ " WHERE ComChtNum = RPAD(:c, 10) AND ComAcpDtm <= :a AND ComAcpStt <> 'OC'"
|
||||
+ " ORDER BY ComAcpDtm) WHERE ROWNUM = 1",
|
||||
("c", chtNum), ("a", acpDtm));
|
||||
|
||||
/// <summary>외래 진료기간 끝(:2352-2372) — 시작 이후 오늘(2359)까지의 최신 접수일시</summary>
|
||||
public string TreatmentPeriodEnd(string chtNum, string strDte)
|
||||
=> Scalar(
|
||||
"SELECT v FROM (SELECT ComAcpDtm v FROM P_ComInf"
|
||||
+ " WHERE ComChtNum = RPAD(:c, 10) AND ComAcpDtm >= :s"
|
||||
+ " AND ComAcpDtm <= TO_CHAR(SYSDATE, 'YYYYMMDD') || '2359' AND ComAcpStt <> 'OC'"
|
||||
+ " ORDER BY ComAcpDtm DESC) WHERE ROWNUM = 1",
|
||||
("c", chtNum), ("s", strDte));
|
||||
|
||||
/// <summary>
|
||||
/// 응급증상 오더의 산정 여부(OCM_응급증상여부_YES/NO, :12748/:12830) — 응급 내원에
|
||||
/// 걸린 응급의료관리료 오더 중 한 행의 OdrInsYon. 행이 없으면 null(레거시 $NoCheck$ —
|
||||
/// 체크 상태를 정하지 않는다). 원문 Rows(0) 에 ORDER BY 가 없다 — 오더일시 최신으로
|
||||
/// 고정한다. 코드 목록은 레거시 GetDtlMst("EMGEMGCOD") 그대로: 코드표에 있으면 그것,
|
||||
/// 없으면 하드코딩 6종(레거시 폴백).
|
||||
/// </summary>
|
||||
public string? EmergencySymptomInsYon(decimal comNum)
|
||||
{
|
||||
var codes = Rows("SELECT DtlCod FROM M_DtlMst WHERE DtlTblCod = 'EMGEMGCOD' ORDER BY DtlCod")
|
||||
.Select(r => r.TryGetValue("DtlCod", out var v) ? v : string.Empty)
|
||||
.Where(v => v.Length > 0)
|
||||
.ToArray();
|
||||
if (codes.Length == 0)
|
||||
{
|
||||
codes = new[] { "V1200", "V1300", "V1400", "V1500", "AC103", "AC105" };
|
||||
}
|
||||
var placeholders = string.Join(", ", codes.Select((_, i) => $":g{i}"));
|
||||
var binds = new List<(string, object)> { ("m", comNum) };
|
||||
for (var i = 0; i < codes.Length; i++)
|
||||
{
|
||||
binds.Add(($"g{i}", codes[i]));
|
||||
}
|
||||
var value = Scalar(
|
||||
"SELECT v FROM (SELECT OdrInsYon v FROM S_EmgInf OCMEMG"
|
||||
+ " LEFT JOIN S_EmgIcmInf ICMEMG ON OCMEMG.EmgComNum = ICMEMG.EmgOcmNum"
|
||||
+ " INNER JOIN O_OdrInf ON CASE WHEN NVL(ICMEMG.EmgComNum, 0) > 0"
|
||||
+ " THEN ICMEMG.EmgComNum ELSE OCMEMG.EmgComNum END = OdrComNum"
|
||||
+ " INNER JOIN O_OdsInf ON OdrKey = OdsOdrKey AND OdsStt = 'OE'"
|
||||
+ " INNER JOIN M_SgaMst ON OdrCod = SgaCod"
|
||||
+ " AND OdrDtm BETWEEN SgaStrDte AND SgaEndDte || '2359'"
|
||||
+ " WHERE OCMEMG.EmgComNum = :m"
|
||||
+ " AND OdrStt = 'OE' AND (OdrHidden IS NULL OR OdrHidden <> 1)"
|
||||
+ $" AND OdrElcCod IN ({placeholders})"
|
||||
+ " ORDER BY OdrDtm DESC, OdrKey DESC) WHERE ROWNUM = 1",
|
||||
binds.ToArray());
|
||||
// 빈 문자열은 "행은 있는데 값이 NULL"과 "행이 없다"를 못 가른다 — COUNT 로 가른다
|
||||
if (value.Length > 0)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
var count = Scalar(
|
||||
"SELECT COUNT(*) FROM S_EmgInf OCMEMG"
|
||||
+ " LEFT JOIN S_EmgIcmInf ICMEMG ON OCMEMG.EmgComNum = ICMEMG.EmgOcmNum"
|
||||
+ " INNER JOIN O_OdrInf ON CASE WHEN NVL(ICMEMG.EmgComNum, 0) > 0"
|
||||
+ " THEN ICMEMG.EmgComNum ELSE OCMEMG.EmgComNum END = OdrComNum"
|
||||
+ " INNER JOIN O_OdsInf ON OdrKey = OdsOdrKey AND OdsStt = 'OE'"
|
||||
+ " INNER JOIN M_SgaMst ON OdrCod = SgaCod"
|
||||
+ " AND OdrDtm BETWEEN SgaStrDte AND SgaEndDte || '2359'"
|
||||
+ " WHERE OCMEMG.EmgComNum = :m"
|
||||
+ " AND OdrStt = 'OE' AND (OdrHidden IS NULL OR OdrHidden <> 1)"
|
||||
+ $" AND OdrElcCod IN ({placeholders})",
|
||||
binds.ToArray());
|
||||
return count == "0" ? null : string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 전과 내역(OCM_전과내역, :1103) — 진료 행 전부를 과명·구간과 함께.
|
||||
/// 원문 조인 그대로: 과 조인이 담당의 조인의 병원 코드에 종속돼(DepHspCod=Usr.UidHspCod)
|
||||
/// 의사 매칭이 빠지면 과명도 빈다. 정렬(CodStrDtm)이 원문부터 있어 결정적이다.
|
||||
/// </summary>
|
||||
public IReadOnlyList<IReadOnlyDictionary<string, string>> TransferHistory(decimal comNum)
|
||||
=> Rows(
|
||||
"SELECT DepKorNam AS DepNam, Cod.CodStrDtm, Cod.CodEndDtm FROM P_CodInf Cod"
|
||||
+ " LEFT OUTER JOIN M_UidMst Usr ON Usr.UidCod = CodDtrCod AND Usr.UidDtrYon = 'Y'"
|
||||
+ " AND Cod.CodEndDtm BETWEEN Usr.UidStrDte AND Usr.UidEndDte || '2359'"
|
||||
+ " LEFT OUTER JOIN M_DepMst Dep ON DepCod = CodDepCod AND DepHspCod = Usr.UidHspCod"
|
||||
+ " AND DepWrkTyp = 'D' AND Cod.CodEndDtm BETWEEN DepStrDte AND DepEndDte || '2359'"
|
||||
+ " WHERE CodComNum = :m AND CodMtiSeq = '0' ORDER BY CodStrDtm",
|
||||
("m", comNum));
|
||||
|
||||
/// <summary>스칼라 1칸 — 0행이거나 NULL 이면 빈 문자열. 잔여 공백은 걷는다(문맥 행과 같은 규칙)</summary>
|
||||
private string Scalar(string sql, params (string Name, object Value)[] binds)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user