STFDTR(주치의)을 옮기고 _Refer 계열의 진실을 밝힌다 — 75종 → 76종 + 사유 정정 ~40종
## OCM_STFDTR 담당의 조회를 코드 컬럼만 일반화했다(CodDtrCod → CodStfDtr 파라미터). 시각 갈래는 담당의와 같다(bzDataInterface.vb:4026-4067). 코드가 비어 있으면 레거시도 즉시 "" — 진료과 행이 돌아오면 주치의 행이 아니므로 비운다. ## _Refer 계열은 "안 옮긴 것"이 아니었다 참조 내원은 EMR 실행 화면(ActionTag — fmCodLstActionTag.vb:54 등)에서 <b>사용자가 지정하는 값</b>이고, 레거시 서식생성기 미리보기(TestPatientSetting)는 그것을 설정하지 않는다. 즉 <b>레거시 미리보기에서도 _Refer 태그는 전부 빈 값</b>이다. 지금까지 그 태그들이 "환자 태그이지만 아직 옮기지 않았습니다"로 나왔는데 그건 틀린 사유다 — 옮길 것이 없는 게 아니라, 이 화면에는 참조 내원이라는 개념 자체가 없다. 사유를 갈랐다: "참조 내원 태그입니다 — 참조 내원은 EMR 실행 화면에서 지정되며, 레거시 미리보기에서도 빈 값입니다". _Refer ~40종의 표시가 이것으로 바뀐다. 이로써 <b>서식생성기 미리보기 기준의 레거시 호환</b>에서 _Refer 계열은 완결이다 — 레거시가 빈 값인 자리는 빈 값(+정확한 사유)이 맞는 이식이다. ## 게이트 - dotnet test 338/338 · --edit-smoke 실패 0(이름 검사 76종) - --db-patient 전건 통과 · --db-render P062 md5 불변 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
26d9606d1e
commit
3e9d5b5cf3
@@ -145,7 +145,9 @@ public sealed class PatientContextStore
|
||||
/// </summary>
|
||||
/// <param name="moment">진료과 행을 고를 적용일시 12자리</param>
|
||||
/// <param name="doctorDay">담당의 유효기간을 볼 날짜 8자리. 비면 <paramref name="moment"/> 의 앞 8자리</param>
|
||||
public IReadOnlyDictionary<string, string> Doctor(decimal comNum, string moment, string? doctorDay = null)
|
||||
/// <param name="codeColumn">진료과 행에서 의사 코드를 집을 컬럼 — 담당의 CodDtrCod, 주치의(전공의) CodStfDtr</param>
|
||||
public IReadOnlyDictionary<string, string> Doctor(decimal comNum, string moment,
|
||||
string? doctorDay = null, string codeColumn = "CodDtrCod")
|
||||
{
|
||||
using var connection = new OracleConnection(connectionString);
|
||||
connection.Open();
|
||||
@@ -154,7 +156,7 @@ public sealed class PatientContextStore
|
||||
"SELECT * FROM (SELECT * FROM P_CodInf WHERE CodComNum = :k AND CodMtiSeq = 0"
|
||||
+ " AND :t BETWEEN CodStrDtm AND CodEndDtm ORDER BY CodStrDtm DESC) WHERE ROWNUM = 1",
|
||||
("k", comNum), ("t", moment));
|
||||
var code = PatientContext.Value(cod, "CodDtrCod");
|
||||
var code = PatientContext.Value(cod, codeColumn);
|
||||
if (code.Length == 0)
|
||||
{
|
||||
return cod;
|
||||
|
||||
@@ -94,6 +94,39 @@ public static class PatientIdentity
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 주치의(전공의) 행 — 진료과 행의 <b>CodStfDtr</b> 로 찾는다. 시각 갈래는 담당의와 같다
|
||||
/// (bzDataInterface.vb:4026-4067). 코드가 비어 있으면 빈 사전 — 레거시도 즉시 "" 다.
|
||||
/// </summary>
|
||||
public static IReadOnlyDictionary<string, string> StaffDoctorOf(PatientContext context)
|
||||
{
|
||||
var connection = ConfigService.Current.ConnectionString;
|
||||
var empty = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
if (connection.Length == 0)
|
||||
{
|
||||
return empty;
|
||||
}
|
||||
var inpatient = PatientContext.Value(context.ComInf, "ComPatTyp") == "I";
|
||||
var accepted = PatientContext.Value(context.ComInf, "ComAcpDtm");
|
||||
var left = PatientContext.Value(context.ComInf, "ComLevDtm");
|
||||
var discharged = PatientContext.Value(context.ComInf, "ComPrgStt") == "ILV";
|
||||
var moment = inpatient
|
||||
? (discharged && left.Length >= 12 ? left[..12] : context.AdpDtm)
|
||||
: (accepted.Length >= 12 ? accepted[..12] : context.AdpDtm);
|
||||
var doctorDay = inpatient ? null : (accepted.Length >= 8 ? accepted[..8] : null);
|
||||
try
|
||||
{
|
||||
var row = new PatientContextStore(connection)
|
||||
.Doctor(context.ComNum, moment, doctorDay, "CodStfDtr");
|
||||
// 코드가 비어 있으면 Doctor 가 진료과 행을 돌려준다 — 주치의 행이 아니므로 비운다
|
||||
return row.ContainsKey("UidNam") ? row : empty;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 상병 행 공급자 — 해석기가 <b>필요할 때</b> 갈래(전체/주/부)별로 부른다.
|
||||
/// 여기서 미리 읽지 않는 이유는 상병 태그가 없는 서식이 다수이기 때문이다.
|
||||
|
||||
@@ -66,7 +66,8 @@ public static class PatientSession
|
||||
SheetMe.Core.Catalog.ITagValueResolver tags = Current is { } picked
|
||||
? new PatientTagResolver(picked, session,
|
||||
PatientIdentity.ResidentNumberOf(picked), PatientIdentity.AddressOf(picked),
|
||||
PatientIdentity.DoctorOf(picked), PatientIdentity.DepartmentOf(picked),
|
||||
PatientIdentity.DoctorOf(picked), PatientIdentity.StaffDoctorOf(picked),
|
||||
PatientIdentity.DepartmentOf(picked),
|
||||
PatientIdentity.HospitalRowOf(picked),
|
||||
PatientIdentity.DiagnosisSourceFor(picked),
|
||||
PatientIdentity.SurgerySourceFor(picked),
|
||||
|
||||
@@ -157,6 +157,9 @@ public sealed class PatientTagResolver : ITagValueResolver
|
||||
/// <summary>이 내원의 담당의 행(M_UidMst) — 없으면 빈 사전</summary>
|
||||
private readonly IReadOnlyDictionary<string, string> doctor;
|
||||
|
||||
/// <summary>이 내원의 주치의(전공의, CodStfDtr) 행 — 없으면 빈 사전</summary>
|
||||
private readonly IReadOnlyDictionary<string, string> staffDoctor;
|
||||
|
||||
/// <summary>이 내원의 진료과 마스터 행(M_DepMst) — 없으면 빈 사전</summary>
|
||||
private readonly IReadOnlyDictionary<string, string> department;
|
||||
|
||||
@@ -187,6 +190,7 @@ public sealed class PatientTagResolver : ITagValueResolver
|
||||
public PatientTagResolver(PatientContext context, ITagValueResolver next,
|
||||
string residentNumber = "", IReadOnlyDictionary<string, string>? address = null,
|
||||
IReadOnlyDictionary<string, string>? doctor = null,
|
||||
IReadOnlyDictionary<string, string>? staffDoctor = null,
|
||||
IReadOnlyDictionary<string, string>? department = null,
|
||||
IReadOnlyDictionary<string, string>? hospital = null,
|
||||
Func<DiagnosisStore.Scope, IReadOnlyList<Dictionary<string, string>>>? diagnosisSource = null,
|
||||
@@ -198,6 +202,7 @@ public sealed class PatientTagResolver : ITagValueResolver
|
||||
this.residentNumber = residentNumber;
|
||||
this.address = address ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
this.doctor = doctor ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
this.staffDoctor = staffDoctor ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
this.department = department ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
this.hospital = hospital ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
this.diagnosisSource = diagnosisSource;
|
||||
@@ -254,6 +259,15 @@ public sealed class PatientTagResolver : ITagValueResolver
|
||||
{
|
||||
return fallback;
|
||||
}
|
||||
// _Refer(참조 내원) 계열은 "안 옮긴 것"이 아니다 — 참조 내원은 EMR 실행 화면
|
||||
// (ActionTag, fmCodLstActionTag.vb:54 등)에서 사용자가 지정하는 값이고,
|
||||
// 레거시 서식생성기 미리보기(TestPatientSetting)도 그것을 설정하지 않아
|
||||
// <b>레거시에서도 이 태그들은 미리보기에서 빈 값</b>이다. 사유를 갈라 말한다.
|
||||
if (tag.EndsWith("_Refer", StringComparison.Ordinal))
|
||||
{
|
||||
return new TagValue(false,
|
||||
"참조 내원 태그입니다 — 참조 내원은 EMR 실행 화면에서 지정되며, 레거시 미리보기에서도 빈 값입니다");
|
||||
}
|
||||
return new TagValue(false, "환자 태그이지만 아직 옮기지 않았습니다");
|
||||
}
|
||||
|
||||
@@ -352,10 +366,22 @@ public sealed class PatientTagResolver : ITagValueResolver
|
||||
private TagValue? FromDoctor(string tag)
|
||||
{
|
||||
if (tag is not ("OCM_담당의사" or "OCM_담당의사_담당의사코드" or "OCM_담당의사_연락처"
|
||||
or "OCM_담당의사_영문" or "OCM_담당의사면허번호" or "OCM_담당의사전문의번호"))
|
||||
or "OCM_담당의사_영문" or "OCM_담당의사면허번호" or "OCM_담당의사전문의번호"
|
||||
or "OCM_STFDTR"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
// STFDTR(주치의/전공의)는 같은 진료과 행의 <b>CodStfDtr</b> 로 찾은 별도 행이다
|
||||
// (bzDataInterface.vb:4026-4067 — 조회 갈래는 담당의와 같고 코드 컬럼만 다르다)
|
||||
if (tag == "OCM_STFDTR")
|
||||
{
|
||||
var stf = staffDoctor.TryGetValue("UidNam", out var sn) ? sn.Trim() : string.Empty;
|
||||
return stf.Length > 0
|
||||
? new TagValue(true, stf)
|
||||
: new TagValue(false, staffDoctor.Count == 0
|
||||
? "이 내원에 주치의(전공의)가 지정되지 않았습니다"
|
||||
: "주치의 이름이 비어 있습니다");
|
||||
}
|
||||
string Field(string column) => doctor.TryGetValue(column, out var v) ? v.Trim() : string.Empty;
|
||||
|
||||
var name = Field("UidNam");
|
||||
@@ -698,7 +724,7 @@ public sealed class PatientTagResolver : ITagValueResolver
|
||||
"ETC_요양기관명칭_병원전화_팩스번호", "ETC_요양기관명칭_영문_병원전화_팩스번호",
|
||||
"ETC_요양기관명칭_병원주소", "ETC_요양기관명칭_병원주소_영문",
|
||||
"ETC_요양기관명칭_사업자등록번호", "ETC_요양기관기호",
|
||||
"OCM_담당의사_영문", "OCM_담당의사면허번호", "OCM_담당의사전문의번호",
|
||||
"OCM_담당의사_영문", "OCM_담당의사면허번호", "OCM_담당의사전문의번호", "OCM_STFDTR",
|
||||
"OCM_User진료과", "OCM_User진료과_한글명칭", "OCM_User진료의사명",
|
||||
"OCM_상병명_가로", "OCM_상병명_세로", "OCM_상병명_영어_가로", "OCM_상병명_영어_세로",
|
||||
"OCM_상병코드_가로", "OCM_상병코드_세로", "OCM_부상병코드", "OCM_부상병POA",
|
||||
|
||||
@@ -223,7 +223,8 @@ public partial class PreviewWindow : Window
|
||||
? session
|
||||
: new PatientTagResolver(picked, session,
|
||||
PatientIdentity.ResidentNumberOf(picked), PatientIdentity.AddressOf(picked),
|
||||
PatientIdentity.DoctorOf(picked), PatientIdentity.DepartmentOf(picked),
|
||||
PatientIdentity.DoctorOf(picked), PatientIdentity.StaffDoctorOf(picked),
|
||||
PatientIdentity.DepartmentOf(picked),
|
||||
PatientIdentity.HospitalRowOf(picked),
|
||||
PatientIdentity.DiagnosisSourceFor(picked),
|
||||
PatientIdentity.SurgerySourceFor(picked),
|
||||
|
||||
Reference in New Issue
Block a user