From adb3572e401bded50b129f8cea6150677dfd536d Mon Sep 17 00:00:00 2001 From: Msystech Date: Wed, 19 Aug 2026 16:33:58 +0900 Subject: [PATCH] =?UTF-8?q?=EC=9E=85=ED=86=B5=EC=9B=90=EA=B5=AC=EB=B6=84?= =?UTF-8?q?=C2=B7=EC=84=B1=EB=B3=84=ED=91=9C=EA=B8=B0=C2=B7=EB=82=B4?= =?UTF-8?q?=EC=9B=90=EC=9D=BC=EC=8B=9C=208=EC=A2=85=20=E2=80=94=20110?= =?UTF-8?q?=EC=A2=85=20=E2=86=92=20118=EC=A2=85,=20=EC=B2=B4=ED=81=AC?= =?UTF-8?q?=EB=A5=98=20SetValue=20=EC=9D=98=EB=AF=B8=EB=A1=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Computed 6종: OCM_입통원구분_입원/통원(Boolean→"True"/"False", bzDataInterface.vb:989/1009, PatTyp=ComPatTyp 는 bzPatientInfo.vb:639), OCM_외래내원일시(:1068), OCM_외래내원일자_영문(:1091 — Data2Format_ENG "MM-DD-YYYY" 는 월 영문화가 아니라 자리 재배열, clsCommonLib.vb:8591), OCM_입원내원일시/일자(:2824/:2840 Case Else — KIMEYE 만 ComTrsDtm, 미이식 주석). FromResidentNumber 2종: PAT_성별_남/여(:317/:338) — F/M→N·Y 변환, 그 외 값은 레거시가 Select Case Else 없이 그대로 돌려주므로 그대로. WithTagValue 에 체크류 갈래 신설: CheckBox/RadioButton 에 태그가 걸리면 Text 치환이 아니라 Checked 를 바꾼다 — 레거시 SetValue 가 "Y"/"TRUE"(대소문자 무시)만 체크로 바꾼다(CheckBox.vb:688-696 · RadioButton.vb:338-351). 값을 Text 에 넣으면 라벨이 "True" 가 된다. 미리보기·인쇄가 같은 BuildPageVisual 경로라 한 곳 수정으로 둘 다 반영. PAT_성별_나이는 AgeCheck 의존이라 나이 계열과 함께 보류. - dotnet test 338/338 · --edit-smoke 실패 0 (이름 검사 118종) - --db-patient ①~㉚ 전건 통과 - --db-render P062 md5 8d683835f5d81e7bb41c79071d6bf954 불변 Co-Authored-By: Claude Fable 5 --- .../Services/PatientTagResolver.cs | 44 +++++++++++++++++++ src/SheetMe.Designer/Services/PrintService.cs | 19 ++++++-- 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/src/SheetMe.Designer/Services/PatientTagResolver.cs b/src/SheetMe.Designer/Services/PatientTagResolver.cs index f9f460f..f442d1b 100644 --- a/src/SheetMe.Designer/Services/PatientTagResolver.cs +++ b/src/SheetMe.Designer/Services/PatientTagResolver.cs @@ -96,6 +96,24 @@ public sealed class PatientTagResolver : ITagValueResolver : $"{PatientContext.Value(c.CowInf, "CowWadCod")} / {PatientContext.Value(c.CowInf, "CowRomCod")}" + $" / {PatientContext.Value(c.CowInf, "CowBedCod")}", + // 입통원구분 — Boolean 반환(bzDataInterface.vb:989, 1009; PatTyp=ComPatTyp 는 + // bzPatientInfo.vb:639). 문자열 "True"/"False" 로 옮긴다 — 레거시 로더가 + // Boolean.ToString 을 SetValue 로 넘기고, 체크류가 "TRUE" 를 체크로 바꾼다 + // (CheckBox.vb:688-696). 인쇄·미리보기의 WithTagValue 가 같은 규칙을 갖는다. + ["OCM_입통원구분_입원"] = c => Com(c, "ComPatTyp") == "I" ? "True" : "False", + ["OCM_입통원구분_통원"] = c => Com(c, "ComPatTyp") == "O" ? "True" : "False", + + // 외래내원일시 — ComAcpDtm[0:12] 를 "9999-99-99 99:99" 로(bzDataInterface.vb:1068) + ["OCM_외래내원일시"] = c => Stamp(Com(c, "ComAcpDtm")), + // 외래내원일자_영문 — Data2Format_ENG "MM-DD-YYYY"(bzDataInterface.vb:1091, + // clsCommonLib.vb:8591-8632). 월 이름 영문화가 아니라 자리 재배열이다. + ["OCM_외래내원일자_영문"] = c => Reorder(Head(Com(c, "ComAcpDtm"), 8), 4, 6, 0), + + // 입원내원일시·일자 — KIMEYE 만 ComTrsDtm, 그 외 ComAcpDtm(bzDataInterface.vb:2824-2850). + // 여기는 Case Else 갈래만 옮겼다 — KIMEYE 배포에서 쓰려면 그 분기를 마저 옮겨야 한다. + ["OCM_입원내원일시"] = c => Stamp(Com(c, "ComAcpDtm")), + ["OCM_입원내원일자"] = c => Hyphenate(Head(Com(c, "ComAcpDtm"), 8)), + // 내원유형 — 입원/응급실/외래(bzDataInterface.vb:2896-2918). // 응급 여부는 내원행의 ComEmgYon 이다. 그 밖의 환자구분은 레거시도 "" 다. ["OCM_내원유형"] = c => Com(c, "ComPatTyp") switch @@ -357,6 +375,31 @@ public sealed class PatientTagResolver : ITagValueResolver ? "주민번호를 읽지 못해 성별을 만들 수 없습니다" : "이 환자의 성별을 판정할 수 없습니다"); } + case "PAT_성별_남": + case "PAT_성별_여": + { + // 성별을 Y/N 표기로 — 체크박스에 걸어 "남 ☑ 여 ☐" 식으로 쓴다 + // (bzDataInterface.vb:317-356). 선행 분기는 PAT_성별과 같다. + // F/M 이외 값은 레거시가 Select Case 에 Else 없이 그대로 돌려준다 — + // 여기서도 그대로 둔다(고치면 없던 체크가 갑자기 생길 수 있다). + var sex = PatientContext.Value(context.CoiInf, "CoiCalCod") + .StartsWith("24", StringComparison.Ordinal) + ? PatientContext.Value(context.PatInf, "PatSexTyp") + : ResidentNumber.SexOf(residentNumber); + var mark = (tag, sex) switch + { + ("PAT_성별_남", "F") => "N", + ("PAT_성별_남", "M") => "Y", + ("PAT_성별_여", "F") => "Y", + ("PAT_성별_여", "M") => "N", + _ => sex, + }; + return mark.Length > 0 + ? new TagValue(true, mark) + : new TagValue(false, residentNumber.Length == 0 + ? "주민번호를 읽지 못해 성별을 만들 수 없습니다" + : "이 환자의 성별을 판정할 수 없습니다"); + } default: return null; } @@ -921,6 +964,7 @@ public sealed class PatientTagResolver : ITagValueResolver public static readonly string[] DerivedTags = { "PAT_주민번호", "PAT_주민번호_Dash", "PAT_성별", "PAT_한글성별", + "PAT_성별_남", "PAT_성별_여", "PAT_우편번호", "PAT_도로명주소", "PAT_지번주소", "PAT_영문도로명주소", "OCM_담당의사", "OCM_담당의사_담당의사코드", "OCM_담당의사_연락처", "OCM_진료과", "ETC_요양기관명칭_병원명", diff --git a/src/SheetMe.Designer/Services/PrintService.cs b/src/SheetMe.Designer/Services/PrintService.cs index 612ef7e..5fd598d 100644 --- a/src/SheetMe.Designer/Services/PrintService.cs +++ b/src/SheetMe.Designer/Services/PrintService.cs @@ -196,11 +196,22 @@ public static class PrintService { return control; } - var text = value.Resolved ? value.Text - : value.Text.Length > 0 ? $"[{label} — {value.Text}]" : $"[{label}]"; - var model = control.Model.Clone(); - model.Props.SetText("Text", text); + if (value.Resolved && control is CheckBoxViewModel or RadioButtonViewModel) + { + // 체크류는 레거시 SetValue 의미론이다 — 값이 "Y" 또는 "TRUE"(대소문자 무시)면 체크, + // 그 외는 언체크(CheckBox.vb:688-696 · RadioButton.vb:338-351). 라벨(Text)은 건드리지 + // 않는다 — 레거시도 체크 상태만 바꾼다. Boolean 태그(입통원구분 등)의 ToString + // "True" 가 이 규칙으로 체크가 된다. 값을 Text 에 넣으면 라벨이 "True" 로 바뀐다. + var upper = value.Text.ToUpperInvariant(); + model.Props.SetText("Checked", upper is "Y" or "TRUE" ? "True" : "False"); + } + else + { + var text = value.Resolved ? value.Text + : value.Text.Length > 0 ? $"[{label} — {value.Text}]" : $"[{label}]"; + model.Props.SetText("Text", text); + } return DocumentMapper.CreateControl(model, control.EffectiveFont, control.Foreground); }