요양기관 12종을 옮긴다 — 왕복 12회를 1회로 접었다. 63종 → 75종
ETC_요양기관명칭_* 계열(bzDataInterface.vb:15656-16709). 12종 전부 <b>같은 조인(M_DepMst⨝M_HspMst)의 다른 컬럼</b>이라는 것을 본문에서 확인했다 — 병원명(이미 이식)·병원명_영문·병원대표자·병원장·병원장귀하·전화번호·팩스번호· 전화_팩스·영문_전화_팩스·주소·주소_영문·사업자등록번호·요양기관기호. 레거시는 태그마다 이 조인을 따로 돌린다(12종 = 왕복 12회). 컬럼 9개를 한 번에 뽑아 행으로 들고, 값 선택은 해석기가 한다. HospitalName(문자열) → HospitalRow(행) 로 일반화했다. 접미·결합도 본문 그대로다: 병원장 = 병원명+"장" / 병원장귀하 = +"장 귀하" 전화_팩스 = "Tel : … FAX : …" / 영문판 = "Tel : +82 - … FAX : +82 - …" 접두·접미가 붙는 태그는 <b>재료 컬럼</b>으로 빈 값을 판정한다 — 병원명이 비면 "장"만 찍히는 것을 값으로 세지 않는다. 실DB 확인: --db-patient ㉔ 가 9열·병원명 6자를 돌려줬다. ## 게이트 - dotnet test 338/338 · --edit-smoke 실패 0(이름 검사 75종) - --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
ef4f36419f
commit
26d9606d1e
@@ -198,26 +198,30 @@ public sealed class PatientContextStore
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 요양기관명 — <c>ETC_요양기관명칭_병원명</c>(bzDataInterface.vb:15792-15860)의 조회.
|
/// 요양기관 행 — <c>ETC_요양기관명칭_*</c> 12종(bzDataInterface.vb:15656-16709)의 공통 조회.
|
||||||
/// <c>M_DepMst ⨝ M_HspMst(DepHspCod=HspCod)</c> 에서 <c>HspInsNam</c> 하나를 뽑아 Trim.
|
/// <c>M_DepMst ⨝ M_HspMst(DepHspCod=HspCod)</c> 에서 병원 컬럼들을 뽑는다.
|
||||||
/// 진료과 코드로 병원을 찾는 구조다 — 다부지(병원 코드가 다른 진료과) 구성 때문으로 보인다.
|
/// 진료과 코드로 병원을 찾는 구조다 — 다부지(병원 코드가 다른 진료과) 구성 때문으로 보인다.
|
||||||
|
///
|
||||||
|
/// 레거시는 태그마다 이 조인을 <b>따로</b> 돌린다(12종 = 왕복 12회).
|
||||||
|
/// 컬럼만 다르므로 한 번에 다 뽑아 행으로 돌려준다 — 값 선택은 해석기가 한다.
|
||||||
|
/// 컬럼 9개는 전부 각 태그 본문의 SELECT 에서 확인한 것이다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string HospitalName(string? depCod, string? day)
|
public IReadOnlyDictionary<string, string> HospitalRow(string? depCod, string? day)
|
||||||
{
|
{
|
||||||
var code = (depCod ?? string.Empty).Trim();
|
var code = (depCod ?? string.Empty).Trim();
|
||||||
var date = (day ?? string.Empty).Trim();
|
var date = (day ?? string.Empty).Trim();
|
||||||
if (code.Length == 0 || date.Length < 8)
|
if (code.Length == 0 || date.Length < 8)
|
||||||
{
|
{
|
||||||
return string.Empty;
|
return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
using var connection = new OracleConnection(connectionString);
|
using var connection = new OracleConnection(connectionString);
|
||||||
connection.Open();
|
connection.Open();
|
||||||
var row = Row(connection,
|
return Row(connection,
|
||||||
"SELECT HspInsNam FROM (SELECT HspInsNam FROM M_DepMst"
|
"SELECT * FROM (SELECT HspInsNam, HspOwnNam, HspTelNum, HspFaxNum,"
|
||||||
|
+ " HspKorAdr, HspEngNam, HspEngAdr, HspRgnNum, HspInsNum FROM M_DepMst"
|
||||||
+ " INNER JOIN M_HspMst ON DepHspCod = HspCod AND :y BETWEEN HspStrDte AND HspEndDte"
|
+ " INNER JOIN M_HspMst ON DepHspCod = HspCod AND :y BETWEEN HspStrDte AND HspEndDte"
|
||||||
+ " WHERE TRIM(DepCod) = :d AND :y BETWEEN DepStrDte AND DepEndDte) WHERE ROWNUM = 1",
|
+ " WHERE TRIM(DepCod) = :d AND :y BETWEEN DepStrDte AND DepEndDte) WHERE ROWNUM = 1",
|
||||||
("d", code), ("y", date[..8]));
|
("d", code), ("y", date[..8]));
|
||||||
return PatientContext.Value(row, "HspInsNam");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -2200,8 +2200,9 @@ public static class DbSmoke
|
|||||||
Check("㉓ 진료과 마스터가 이름을 돌려준다", korNam.Trim().Length > 0,
|
Check("㉓ 진료과 마스터가 이름을 돌려준다", korNam.Trim().Length > 0,
|
||||||
$"코드 '{depCod}' 로 M_DepMst 에서 이름을 못 찾았다");
|
$"코드 '{depCod}' 로 M_DepMst 에서 이름을 못 찾았다");
|
||||||
|
|
||||||
var hosp = contexts.HospitalName(depCod, octx.AdpDtm);
|
var hospRow = contexts.HospitalRow(depCod, octx.AdpDtm);
|
||||||
lines.Add($" 요양기관명: {hosp.Length}자");
|
var hosp = PatientContext.Value(hospRow, "HspInsNam");
|
||||||
|
lines.Add($" 요양기관: {hospRow.Count}열, 병원명 {hosp.Length}자");
|
||||||
Check("㉔ 요양기관명이 나온다", hosp.Trim().Length > 0,
|
Check("㉔ 요양기관명이 나온다", hosp.Trim().Length > 0,
|
||||||
"M_DepMst⨝M_HspMst 조인이 0행 — 유효기간이나 DepHspCod 를 의심할 것");
|
"M_DepMst⨝M_HspMst 조인이 0행 — 유효기간이나 DepHspCod 를 의심할 것");
|
||||||
|
|
||||||
|
|||||||
@@ -154,25 +154,26 @@ public static class PatientIdentity
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 요양기관명 — 못 읽으면 빈 문자열.
|
/// 요양기관 행 — 못 읽으면 빈 사전.
|
||||||
/// 판정 일자가 진료과와 <b>다르다</b>(bzDataInterface.vb:15815-15825):
|
/// 판정 일자가 진료과와 <b>다르다</b>(bzDataInterface.vb:15815-15825):
|
||||||
/// 입원·퇴원(ILV)은 퇴원일시, 입원 중은 지금, 외래는 접수일시 — 문맥의 적용일시가 그 판정과 같다.
|
/// 입원·퇴원(ILV)은 퇴원일시, 입원 중은 지금, 외래는 접수일시 — 문맥의 적용일시가 그 판정과 같다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string HospitalNameOf(PatientContext context)
|
public static IReadOnlyDictionary<string, string> HospitalRowOf(PatientContext context)
|
||||||
{
|
{
|
||||||
var connection = ConfigService.Current.ConnectionString;
|
var connection = ConfigService.Current.ConnectionString;
|
||||||
|
var empty = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
if (connection.Length == 0)
|
if (connection.Length == 0)
|
||||||
{
|
{
|
||||||
return string.Empty;
|
return empty;
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return new PatientContextStore(connection).HospitalName(
|
return new PatientContextStore(connection).HospitalRow(
|
||||||
PatientContext.Value(context.CodInf, "CodDepCod"), context.AdpDtm);
|
PatientContext.Value(context.CodInf, "CodDepCod"), context.AdpDtm);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
return string.Empty;
|
return empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public static class PatientSession
|
|||||||
? new PatientTagResolver(picked, session,
|
? new PatientTagResolver(picked, session,
|
||||||
PatientIdentity.ResidentNumberOf(picked), PatientIdentity.AddressOf(picked),
|
PatientIdentity.ResidentNumberOf(picked), PatientIdentity.AddressOf(picked),
|
||||||
PatientIdentity.DoctorOf(picked), PatientIdentity.DepartmentOf(picked),
|
PatientIdentity.DoctorOf(picked), PatientIdentity.DepartmentOf(picked),
|
||||||
PatientIdentity.HospitalNameOf(picked),
|
PatientIdentity.HospitalRowOf(picked),
|
||||||
PatientIdentity.DiagnosisSourceFor(picked),
|
PatientIdentity.DiagnosisSourceFor(picked),
|
||||||
PatientIdentity.SurgerySourceFor(picked),
|
PatientIdentity.SurgerySourceFor(picked),
|
||||||
PatientIdentity.ReviewDiagnosisSourceFor(picked))
|
PatientIdentity.ReviewDiagnosisSourceFor(picked))
|
||||||
|
|||||||
@@ -160,8 +160,8 @@ public sealed class PatientTagResolver : ITagValueResolver
|
|||||||
/// <summary>이 내원의 진료과 마스터 행(M_DepMst) — 없으면 빈 사전</summary>
|
/// <summary>이 내원의 진료과 마스터 행(M_DepMst) — 없으면 빈 사전</summary>
|
||||||
private readonly IReadOnlyDictionary<string, string> department;
|
private readonly IReadOnlyDictionary<string, string> department;
|
||||||
|
|
||||||
/// <summary>요양기관명(HspInsNam) — 못 읽었으면 빈 문자열</summary>
|
/// <summary>요양기관 행(M_HspMst 컬럼들) — 없으면 빈 사전</summary>
|
||||||
private readonly string hospitalName;
|
private readonly IReadOnlyDictionary<string, string> hospital;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 상병 행 공급자 — 주/부/전체 별로 <b>물을 때 한 번만</b> 읽는다.
|
/// 상병 행 공급자 — 주/부/전체 별로 <b>물을 때 한 번만</b> 읽는다.
|
||||||
@@ -187,7 +187,8 @@ public sealed class PatientTagResolver : ITagValueResolver
|
|||||||
public PatientTagResolver(PatientContext context, ITagValueResolver next,
|
public PatientTagResolver(PatientContext context, ITagValueResolver next,
|
||||||
string residentNumber = "", IReadOnlyDictionary<string, string>? address = null,
|
string residentNumber = "", IReadOnlyDictionary<string, string>? address = null,
|
||||||
IReadOnlyDictionary<string, string>? doctor = null,
|
IReadOnlyDictionary<string, string>? doctor = null,
|
||||||
IReadOnlyDictionary<string, string>? department = null, string hospitalName = "",
|
IReadOnlyDictionary<string, string>? department = null,
|
||||||
|
IReadOnlyDictionary<string, string>? hospital = null,
|
||||||
Func<DiagnosisStore.Scope, IReadOnlyList<Dictionary<string, string>>>? diagnosisSource = null,
|
Func<DiagnosisStore.Scope, IReadOnlyList<Dictionary<string, string>>>? diagnosisSource = null,
|
||||||
Func<IReadOnlyList<Dictionary<string, string>>>? surgerySource = null,
|
Func<IReadOnlyList<Dictionary<string, string>>>? surgerySource = null,
|
||||||
Func<DiagnosisStore.Scope, IReadOnlyList<Dictionary<string, string>>>? reviewSource = null)
|
Func<DiagnosisStore.Scope, IReadOnlyList<Dictionary<string, string>>>? reviewSource = null)
|
||||||
@@ -198,7 +199,7 @@ public sealed class PatientTagResolver : ITagValueResolver
|
|||||||
this.address = address ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
this.address = address ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
this.doctor = doctor ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
this.doctor = doctor ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
this.department = department ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
this.department = department ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
this.hospitalName = hospitalName;
|
this.hospital = hospital ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
this.diagnosisSource = diagnosisSource;
|
this.diagnosisSource = diagnosisSource;
|
||||||
this.surgerySource = surgerySource;
|
this.surgerySource = surgerySource;
|
||||||
this.reviewSource = reviewSource;
|
this.reviewSource = reviewSource;
|
||||||
@@ -401,10 +402,59 @@ public sealed class PatientTagResolver : ITagValueResolver
|
|||||||
? "이 내원의 진료과를 찾지 못했습니다"
|
? "이 내원의 진료과를 찾지 못했습니다"
|
||||||
: "진료과 마스터에 이름이 비어 있습니다");
|
: "진료과 마스터에 이름이 비어 있습니다");
|
||||||
}
|
}
|
||||||
|
// ── 요양기관 12종 — 같은 조인의 다른 컬럼(bzDataInterface.vb:15656-16709) ──
|
||||||
|
// 접미·결합도 본문 그대로: 병원장 = 병원명+"장", 귀하 = +"장 귀하",
|
||||||
|
// 전화_팩스 = "Tel : … FAX : …", 영문판은 "+82 - " 접두가 붙는다.
|
||||||
case "ETC_요양기관명칭_병원명":
|
case "ETC_요양기관명칭_병원명":
|
||||||
return hospitalName.Trim().Length > 0
|
case "ETC_요양기관명칭_병원명_영문":
|
||||||
? new TagValue(true, hospitalName.Trim())
|
case "ETC_요양기관명칭_병원대표자":
|
||||||
: new TagValue(false, "요양기관명을 찾지 못했습니다(M_DepMst·M_HspMst 조인)");
|
case "ETC_요양기관명칭_병원장":
|
||||||
|
case "ETC_요양기관명칭_병원장귀하":
|
||||||
|
case "ETC_요양기관명칭_병원전화번호":
|
||||||
|
case "ETC_요양기관명칭_병원팩스번호":
|
||||||
|
case "ETC_요양기관명칭_병원전화_팩스번호":
|
||||||
|
case "ETC_요양기관명칭_영문_병원전화_팩스번호":
|
||||||
|
case "ETC_요양기관명칭_병원주소":
|
||||||
|
case "ETC_요양기관명칭_병원주소_영문":
|
||||||
|
case "ETC_요양기관명칭_사업자등록번호":
|
||||||
|
case "ETC_요양기관기호":
|
||||||
|
{
|
||||||
|
if (hospital.Count == 0)
|
||||||
|
{
|
||||||
|
return new TagValue(false, "요양기관 정보를 찾지 못했습니다(M_DepMst·M_HspMst 조인)");
|
||||||
|
}
|
||||||
|
string Hsp(string column) => hospital.TryGetValue(column, out var v) ? v.Trim() : string.Empty;
|
||||||
|
|
||||||
|
var hspValue = tag switch
|
||||||
|
{
|
||||||
|
"ETC_요양기관명칭_병원명" => Hsp("HspInsNam"),
|
||||||
|
"ETC_요양기관명칭_병원명_영문" => Hsp("HspEngNam"),
|
||||||
|
"ETC_요양기관명칭_병원대표자" => Hsp("HspOwnNam"),
|
||||||
|
"ETC_요양기관명칭_병원장" => Hsp("HspInsNam") + "장",
|
||||||
|
"ETC_요양기관명칭_병원장귀하" => Hsp("HspInsNam") + "장 귀하",
|
||||||
|
"ETC_요양기관명칭_병원전화번호" => Hsp("HspTelNum"),
|
||||||
|
"ETC_요양기관명칭_병원팩스번호" => Hsp("HspFaxNum"),
|
||||||
|
"ETC_요양기관명칭_병원전화_팩스번호" =>
|
||||||
|
$"Tel : {Hsp("HspTelNum")} FAX : {Hsp("HspFaxNum")}",
|
||||||
|
"ETC_요양기관명칭_영문_병원전화_팩스번호" =>
|
||||||
|
$"Tel : +82 - {Hsp("HspTelNum")} FAX : +82 - {Hsp("HspFaxNum")}",
|
||||||
|
"ETC_요양기관명칭_병원주소" => Hsp("HspKorAdr"),
|
||||||
|
"ETC_요양기관명칭_병원주소_영문" => Hsp("HspEngAdr"),
|
||||||
|
"ETC_요양기관명칭_사업자등록번호" => Hsp("HspRgnNum"),
|
||||||
|
_ => Hsp("HspInsNum"),
|
||||||
|
};
|
||||||
|
// 병원장·전화_팩스는 접두·접미가 붙어 "장"만 남을 수 있다 — 재료 컬럼으로 빈 값을 판정한다
|
||||||
|
var material = tag switch
|
||||||
|
{
|
||||||
|
"ETC_요양기관명칭_병원장" or "ETC_요양기관명칭_병원장귀하" => Hsp("HspInsNam"),
|
||||||
|
"ETC_요양기관명칭_병원전화_팩스번호" or "ETC_요양기관명칭_영문_병원전화_팩스번호"
|
||||||
|
=> Hsp("HspTelNum") + Hsp("HspFaxNum"),
|
||||||
|
_ => hspValue,
|
||||||
|
};
|
||||||
|
return material.Trim().Length > 0
|
||||||
|
? new TagValue(true, hspValue)
|
||||||
|
: new TagValue(false, "요양기관 행은 있는데 그 값이 비어 있습니다");
|
||||||
|
}
|
||||||
|
|
||||||
// ── User 계열 — 로그인 사용자가 의사면 <b>사용자의</b> 과·이름, 아니면 환자의 것 ──
|
// ── User 계열 — 로그인 사용자가 의사면 <b>사용자의</b> 과·이름, 아니면 환자의 것 ──
|
||||||
// (bzDataInterface.vb:5697-5826). 개원일 조건(HspStrDte>=20220701)은 세션에 없어
|
// (bzDataInterface.vb:5697-5826). 개원일 조건(HspStrDte>=20220701)은 세션에 없어
|
||||||
@@ -642,6 +692,12 @@ public sealed class PatientTagResolver : ITagValueResolver
|
|||||||
"PAT_우편번호", "PAT_도로명주소", "PAT_지번주소", "PAT_영문도로명주소",
|
"PAT_우편번호", "PAT_도로명주소", "PAT_지번주소", "PAT_영문도로명주소",
|
||||||
"OCM_담당의사", "OCM_담당의사_담당의사코드", "OCM_담당의사_연락처",
|
"OCM_담당의사", "OCM_담당의사_담당의사코드", "OCM_담당의사_연락처",
|
||||||
"OCM_진료과", "ETC_요양기관명칭_병원명",
|
"OCM_진료과", "ETC_요양기관명칭_병원명",
|
||||||
|
"ETC_요양기관명칭_병원명_영문", "ETC_요양기관명칭_병원대표자",
|
||||||
|
"ETC_요양기관명칭_병원장", "ETC_요양기관명칭_병원장귀하",
|
||||||
|
"ETC_요양기관명칭_병원전화번호", "ETC_요양기관명칭_병원팩스번호",
|
||||||
|
"ETC_요양기관명칭_병원전화_팩스번호", "ETC_요양기관명칭_영문_병원전화_팩스번호",
|
||||||
|
"ETC_요양기관명칭_병원주소", "ETC_요양기관명칭_병원주소_영문",
|
||||||
|
"ETC_요양기관명칭_사업자등록번호", "ETC_요양기관기호",
|
||||||
"OCM_담당의사_영문", "OCM_담당의사면허번호", "OCM_담당의사전문의번호",
|
"OCM_담당의사_영문", "OCM_담당의사면허번호", "OCM_담당의사전문의번호",
|
||||||
"OCM_User진료과", "OCM_User진료과_한글명칭", "OCM_User진료의사명",
|
"OCM_User진료과", "OCM_User진료과_한글명칭", "OCM_User진료의사명",
|
||||||
"OCM_상병명_가로", "OCM_상병명_세로", "OCM_상병명_영어_가로", "OCM_상병명_영어_세로",
|
"OCM_상병명_가로", "OCM_상병명_세로", "OCM_상병명_영어_가로", "OCM_상병명_영어_세로",
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ public partial class PreviewWindow : Window
|
|||||||
: new PatientTagResolver(picked, session,
|
: new PatientTagResolver(picked, session,
|
||||||
PatientIdentity.ResidentNumberOf(picked), PatientIdentity.AddressOf(picked),
|
PatientIdentity.ResidentNumberOf(picked), PatientIdentity.AddressOf(picked),
|
||||||
PatientIdentity.DoctorOf(picked), PatientIdentity.DepartmentOf(picked),
|
PatientIdentity.DoctorOf(picked), PatientIdentity.DepartmentOf(picked),
|
||||||
PatientIdentity.HospitalNameOf(picked),
|
PatientIdentity.HospitalRowOf(picked),
|
||||||
PatientIdentity.DiagnosisSourceFor(picked),
|
PatientIdentity.DiagnosisSourceFor(picked),
|
||||||
PatientIdentity.SurgerySourceFor(picked),
|
PatientIdentity.SurgerySourceFor(picked),
|
||||||
PatientIdentity.ReviewDiagnosisSourceFor(picked));
|
PatientIdentity.ReviewDiagnosisSourceFor(picked));
|
||||||
|
|||||||
Reference in New Issue
Block a user