HL7 Vietnam VN Core FHIR Implementation Guide

Bộ Hướng dẫn Triển khai Core FHIR cho Việt Nam
0.8.0 - Draft for Community Review Viet Nam cờ

Bộ Hướng dẫn Triển khai Core FHIR cho Việt Nam - Draft for Community Review (v0.8.0) built by the FHIR (HL7® FHIR® Standard) Build Tools. See the Directory of published versions

StructureMap: Bảng 3 DVKT và vật tư BHYT — Logical Model — StructureMap

URL chính thức: http://fhir.hl7.org.vn/core/StructureMap/vn-sm-bhyt-xml3-service Phiên bản: 0.8.0
Computable Name: BHYTXML3ServiceLMStructureMap
Định danh khác: OID:2.25.161089673617632664299011809196868855799.43.6

Generated StructureMap scaffold for Bảng 3 DVKT và vật tư BHYT — Logical Model. Source semantics come from the logical model mapping annotations in BHYTXML3ServiceLM.fsh and remain aligned with the Python BHYT round-trip export adapter.

Language: vi

map "http://fhir.hl7.org.vn/core/StructureMap/vn-sm-bhyt-xml3-service" = "BHYTXML3ServiceLMStructureMap"

// Generated StructureMap scaffold for Bảng 3 DVKT và vật tư BHYT — Logical Model. Source semantics come from the logical model mapping annotations in `BHYTXML3ServiceLM.fsh` and remain aligned with the Python BHYT round-trip export adapter.

// FHIR-native source bundle profile used by the repository round-trip adapter.
uses "http://fhir.hl7.org.vn/core/StructureDefinition/vn-core-bhyt-submission-bundle" alias BHYTSubmissionBundle as source
// Bảng 3 DVKT và vật tư BHYT — Logical Model
uses "http://fhir.hl7.org.vn/core/StructureDefinition/bhytXml3ServiceLm" alias BHYTXML3ServiceLM as target

// Full QD 3176 XML3 field catalog. Rows are derived from non-medication service, supply, device, procedure, and bed-day claim items. Generated from logical-model `^mapping` annotations. Fields still missing a field-level `^mapping.map` entry remain outside this StructureMap and are tracked in `wiki/mappings/bhyt-output-data/machine/structuremap-coverage.json`.
group MapBHYTXML3ServiceLM(source sourceBundle : BHYTSubmissionBundle, target targetRow : BHYTXML3ServiceLM) {
  // Target field: MA_LK - Mã liên kết hồ sơ FHIR path: VNCoreClaim.identifier[MALK].value
  sourceBundle.entry 0..* as maLkSource -> targetRow.maLk "maLk";
  // Target field: STT - Số thứ tự dòng FHIR path: VNCoreClaim.item.where(category!='8').sequence
  sourceBundle.entry 0..* as sttSource -> targetRow.stt "stt";
  // Target field: MA_DICH_VU - Mã dịch vụ kỹ thuật FHIR path: VNCoreClaim.item.where(category!='8').productOrService.coding.code | VNCoreServiceRequest.code.coding.code Mapping note: Conditionally required when MA_VAT_TU is absent or MA_NHOM is not 10.
  sourceBundle.entry 0..* as maDichVuSource -> targetRow.maDichVu "maDichVu";
  // Target field: MA_PTTT_QT - Mã phương thức thanh toán FHIR path: VNCoreClaim.extension[paymentMethod].valueCodeableConcept.coding.code | VNCoreClaim.item.extension[paymentMethod].valueCodeableConcept.coding.code
  sourceBundle.entry 0..* as maPtttQtSource -> targetRow.maPtttQt "maPtttQt";
  // Target field: MA_VAT_TU - Mã vật tư y tế FHIR path: VNCoreDevice.identifier[medicalDeviceItemCode].value | VNCoreClaim.item.where(category!='8').productOrService.coding.code Mapping note: Conditionally required when MA_DICH_VU is absent or MA_NHOM=10; do not collapse medical supplies into service codes when Device is available.
  sourceBundle.entry 0..* as maVatTuSource -> targetRow.maVatTu "maVatTu";
  // Target field: MA_NHOM - Mã nhóm chi phí theo QĐ 3176/QĐ-BYT FHIR path: ConceptMap/vn-cm-bhyt-claim-cost-group-to-cost-category -> VNCoreClaim.item.where(category!='8').category.coding.code Mapping note: Source code system is QD 3176 MA_NHOM. Export/import must bridge through the ConceptMap instead of assigning the QD 697 target code directly.
  sourceBundle.entry 0..* as maNhomSource -> targetRow.maNhom "maNhom";
  // Target field: GOI_VTYT - Gói vật tư y tế FHIR path: VNCoreClaim.item.where(category!='8') | future supply-package (GOI_VTYT) extension Mapping note: Mã gói VTYT trong một lần dùng DVKT (G1, G2,...) theo QĐ 3176/QĐ-BYT; ghi tại dòng DVKT phát sinh gói VTYT đi kèm → điều kiện, 0..1. Chưa có element đích — dùng future extension nhóm gói VTYT trên Claim.item (tiền lệ taiSuDung).
  sourceBundle.entry 0..* as goiVtytSource -> targetRow.goiVtyt "goiVtyt";
  // Target field: TEN_VAT_TU - Tên vật tư y tế FHIR path: VNCoreDevice.deviceName.name | VNCoreClaim.item.where(category!='8').productOrService.text | display
  sourceBundle.entry 0..* as tenVatTuSource -> targetRow.tenVatTu "tenVatTu";
  // Target field: TEN_DICH_VU - Tên dịch vụ kỹ thuật FHIR path: VNCoreClaim.item.where(category!='8').productOrService.text | VNCoreServiceRequest.code.text | display
  sourceBundle.entry 0..* as tenDichVuSource -> targetRow.tenDichVu "tenDichVu";
  // Target field: MA_XANG_DAU - Mã xăng dầu FHIR path: VNCoreClaim.item.where(category!='8') | future fuel-type-code (MA_XANG_DAU) extension Mapping note: Mã loại xăng, dầu để tính chi phí vận chuyển người bệnh theo Bộ mã DMDC do Bộ Y tế ban hành (QĐ 3176/QĐ-BYT); chỉ áp cho dòng vận chuyển (MA_DICH_VU=VC.XXXXX) → điều kiện, 0..1. Chưa có element đích — dùng future extension mã nhiên liệu trên Claim.item.
  sourceBundle.entry 0..* as maXangDauSource -> targetRow.maXangDau "maXangDau";
  // Target field: DON_VI_TINH - Đơn vị tính FHIR path: VNCoreClaim.item.where(category!='8').quantity.unit
  sourceBundle.entry 0..* as donViTinhSource -> targetRow.donViTinh "donViTinh";
  // Target field: PHAM_VI - Phạm vi thanh toán FHIR path: VNCoreClaim.item.where(category!='8').extension[insuranceCostInfo].extension[scope].valueCodeableConcept
  sourceBundle.entry 0..* as phamViSource -> targetRow.phamVi "phamVi";
  // Target field: SO_LUONG - Số lượng FHIR path: VNCoreClaim.item.where(category!='8').quantity.value
  sourceBundle.entry 0..* as soLuongSource -> targetRow.soLuong "soLuong";
  // Target field: DON_GIA_BV - Đơn giá bệnh viện FHIR path: VNCoreClaim.item.where(category!='8').unitPrice.value | VNCoreClaim.item.extension[hospitalUnitPrice].valueMoney.value Mapping note: Hospital charge price; keep separate from the BHYT price to avoid financial round-trip loss.
  sourceBundle.entry 0..* as donGiaBvSource -> targetRow.donGiaBv "donGiaBv";
  // Target field: DON_GIA_BH - Đơn giá BHYT FHIR path: VNCoreClaim.item.where(category!='8').extension[insuranceCostInfo].extension[insuranceUnitPrice].valueMoney.value Mapping note: BHYT-covered unit price; do not collapse into Claim.item.unitPrice when hospital and insurance prices differ.
  sourceBundle.entry 0..* as donGiaBhSource -> targetRow.donGiaBh "donGiaBh";
  // Target field: TT_THAU - Thông tin thầu FHIR path: VNCoreClaim.item.where(category!='8').extension[tenderInfo].valueString Mapping note: Chuỗi thông tin thầu VTYT: số QĐ trúng thầu; số gói thầu; mã nhóm thầu (Phụ lục 7 QĐ 5937/QĐ-BYT); năm ban hành, cách nhau bằng ';' (QĐ 3176/QĐ-BYT). Đính chính: tăng kích thước tối đa lên 50 ký tự; VTYT đấu thầu/duyệt kế hoạch từ 14/4/2023 tạm dùng mã nhóm thầu 'N0'. Đích: extension VNCoreExtTenderInfo (value string) đã tồn tại trên Claim.item. Ghi chú scope: TT_THAU chỉ áp cho dòng VTYT (điều kiện) nhưng cardinality hiện giữ 1..1 theo bản gốc — không sửa trong lượt bổ sung mapping này.
  sourceBundle.entry 0..* as ttThauSource -> targetRow.ttThau "ttThau";
  // Target field: TYLE_TT_DV - Tỷ lệ thanh toán dịch vụ FHIR path: VNCoreClaim.item.where(category!='8').extension[insuranceCostInfo].extension[servicePaymentRatio].valueDecimal
  sourceBundle.entry 0..* as tyleTtDvSource -> targetRow.tyleTtDv "tyleTtDv";
  // Target field: TYLE_TT_BH - Tỷ lệ thanh toán BHYT FHIR path: VNCoreClaim.item.where(category!='8').extension[insuranceCostInfo].extension[paymentRatio].valueDecimal
  sourceBundle.entry 0..* as tyleTtBhSource -> targetRow.tyleTtBh "tyleTtBh";
  // Target field: THANH_TIEN_BV - Thành tiền bệnh viện FHIR path: VNCoreClaim.item.where(category!='8').net.value | VNCoreClaim.item.extension[hospitalLineAmount].valueMoney.value Mapping note: Hospital line amount; keep separate from BHYT line amount.
  sourceBundle.entry 0..* as thanhTienBvSource -> targetRow.thanhTienBv "thanhTienBv";
  // Target field: THANH_TIEN_BH - Thành tiền BHYT FHIR path: VNCoreClaim.item.where(category!='8').extension[insuranceCostInfo].extension[insuranceLineAmount].valueMoney.value
  sourceBundle.entry 0..* as thanhTienBhSource -> targetRow.thanhTienBh "thanhTienBh";
  // Target field: T_TRANTT - Mức trần thanh toán BHYT của gói VTYT FHIR path: VNCoreClaim.item.where(category!='8').extension[insuranceCostInfo].extension[paymentCeiling].valueMoney.value Mapping note: Mức thanh toán tối đa BHYT (45 tháng lương cơ sở) của gói VTYT trong một lần thực hiện DVKT theo Thông tư 04/2017/TT-BYT (diễn giải sửa đổi toàn bộ theo QĐ 3176/QĐ-BYT; kế thừa QĐ 4750/QĐ-BYT); trần 45 tháng lương cơ sở theo NĐ 188/2025/NĐ-CP. Chỉ ghi khi VTYT có quy định mức thanh toán BHYT, để trống khi không có trần → điều kiện, 0..1. Quan hệ tính toán: khi DON_GIA_BV vượt trần thì DON_GIA_BH = T_TRANTT. Đích là sub-extension paymentCeiling (valueMoney) của VNCoreExtInsuranceCostInfo trên Claim.item, tránh gộp mất dữ liệu vào insuranceUnitPrice.
  sourceBundle.entry 0..* as tTranttSource -> targetRow.tTrantt "tTrantt";
  // Target field: MUC_HUONG - Mức hưởng FHIR path: VNCoreClaim.item.where(category!='8').extension[insuranceCostInfo].extension[benefitLevel].valueDecimal Mapping note: QĐ 1931/QĐ-BYT (29/06/2026) sửa đổi QĐ 3176/QĐ-BYT: kích thước tối đa của MUC_HUONG tại Bảng 3 tăng lên 4 ký tự.
  sourceBundle.entry 0..* as mucHuongSource -> targetRow.mucHuong "mucHuong";
  // Target field: T_NGUONKHAC_NSNN - Nguồn khác ngân sách nhà nước FHIR path: VNCoreClaim.item.where(category!='8').extension[otherFundBreakdown].extension[stateBudget].valueMoney.value Mapping note: Số tiền DVKT/VTYT được ngân sách nhà nước (Trung ương và/hoặc địa phương) hỗ trợ theo QĐ 3176/QĐ-BYT, làm tròn 2 chữ số thập phân. Đích line-level là sub-extension stateBudget của VNCoreExtOtherFundBreakdown trên Claim.item; tổng hợp toàn hồ sơ tại Claim.extension[costSummary].extension[totalOtherFund].
  sourceBundle.entry 0..* as tNguonkhacNsnnSource -> targetRow.tNguonkhacNsnn "tNguonkhacNsnn";
  // Target field: T_NGUONKHAC_VTNN - Nguồn khác viện trợ nước ngoài FHIR path: VNCoreClaim.item.where(category!='8').extension[otherFundBreakdown].extension[foreignAid].valueMoney.value Mapping note: Số tiền DVKT/VTYT được tổ chức/cá nhân có trụ sở hoặc đang sinh sống, học tập, lao động ngoài lãnh thổ Việt Nam hỗ trợ (QĐ 3176/QĐ-BYT). Đích line-level là sub-extension foreignAid của VNCoreExtOtherFundBreakdown trên Claim.item.
  sourceBundle.entry 0..* as tNguonkhacVtnnSource -> targetRow.tNguonkhacVtnn "tNguonkhacVtnn";
  // Target field: T_NGUONKHAC_VTTN - Nguồn khác viện trợ trong nước FHIR path: VNCoreClaim.item.where(category!='8').extension[otherFundBreakdown].extension[domesticAid].valueMoney.value Mapping note: Số tiền DVKT/VTYT được tổ chức/cá nhân có trụ sở hoặc đang sinh sống, học tập, lao động trong lãnh thổ Việt Nam hỗ trợ (QĐ 3176/QĐ-BYT). Đích line-level là sub-extension domesticAid của VNCoreExtOtherFundBreakdown trên Claim.item.
  sourceBundle.entry 0..* as tNguonkhacVttnSource -> targetRow.tNguonkhacVttn "tNguonkhacVttn";
  // Target field: T_NGUONKHAC_CL - Nguồn khác còn lại FHIR path: VNCoreClaim.item.where(category!='8').extension[otherFundBreakdown].extension[otherRemaining].valueMoney.value Mapping note: Số tiền DVKT/VTYT từ các nguồn khác còn lại, không thuộc ba nguồn NSNN/VTNN/VTTN (QĐ 3176/QĐ-BYT). Đích line-level là sub-extension otherRemaining của VNCoreExtOtherFundBreakdown trên Claim.item.
  sourceBundle.entry 0..* as tNguonkhacClSource -> targetRow.tNguonkhacCl "tNguonkhacCl";
  // Target field: T_NGUONKHAC - Tổng nguồn khác FHIR path: VNCoreClaim.item.where(category!='8').extension[otherFundBreakdown] (tổng = stateBudget + foreignAid + domesticAid + otherRemaining) Mapping note: Tổng nguồn khác line-level = T_NGUONKHAC_NSNN + T_NGUONKHAC_VTNN + T_NGUONKHAC_VTTN + T_NGUONKHAC_CL (sửa đổi toàn bộ theo QĐ 3176/QĐ-BYT); khi >0 giảm trừ lần lượt vào T_BNTT, T_BNCCT, T_BHTT đến khi hết. 4 thành phần tách theo dòng qua VNCoreExtOtherFundBreakdown trên Claim.item; tổng toàn hồ sơ ánh xạ VNCoreClaim.extension[costSummary].extension[totalOtherFund].valueMoney.value (xem BHYTXML1SummaryLM).
  sourceBundle.entry 0..* as tNguonkhacSource -> targetRow.tNguonkhac "tNguonkhac";
  // Target field: T_BNTT - Người bệnh tự trả FHIR path: Derived from VNCoreClaimResponse.item[serviceLine].adjudication.where(category='submitted').amount - .where(category='eligible').amount | Derived from VNCoreExplanationOfBenefit.item[serviceLine].adjudication.where(category='submitted').amount - .where(category='eligible').amount
  sourceBundle.entry 0..* as tBnttSource -> targetRow.tBntt "tBntt";
  // Target field: T_BNCCT - Người bệnh cùng chi trả FHIR path: VNCoreClaimResponse.item[serviceLine].adjudication.where(category='copay').amount.value | VNCoreExplanationOfBenefit.item[serviceLine].adjudication.where(category='copay').amount.value
  sourceBundle.entry 0..* as tBncctSource -> targetRow.tBncct "tBncct";
  // Target field: T_BHTT - Quỹ BHYT thanh toán FHIR path: VNCoreClaimResponse.item[serviceLine].adjudication.where(category='benefit').amount.value | VNCoreExplanationOfBenefit.item[serviceLine].adjudication.where(category='benefit').amount.value
  sourceBundle.entry 0..* as tBhttSource -> targetRow.tBhtt "tBhtt";
  // Target field: MA_KHOA - Mã khoa FHIR path: VNCoreClaim.item.where(category!='8').extension[department].valueCodeableConcept.coding.code
  sourceBundle.entry 0..* as maKhoaSource -> targetRow.maKhoa "maKhoa";
  // Target field: MA_GIUONG - Mã giường FHIR path: VNCoreEncounter.location.location.resolve().identifier.value Mapping note: Conditionally required for bed-day MA_NHOM values 14, 15, 16.
  sourceBundle.entry 0..* as maGiuongSource -> targetRow.maGiuong "maGiuong";
  // Target field: MA_BAC_SI - Mã bác sĩ FHIR path: VNCoreServiceRequest.requester.resolve().identifier.value | VNCoreProcedure.performer.actor.resolve().identifier.value | VNCorePractitioner.identifier.value
  sourceBundle.entry 0..* as maBacSiSource -> targetRow.maBacSi "maBacSi";
  // Target field: NGUOI_THUC_HIEN - Người thực hiện FHIR path: VNCoreProcedure.performer.actor.resolve().identifier.value | VNCorePractitioner.identifier.value
  sourceBundle.entry 0..* as nguoiThucHienSource -> targetRow.nguoiThucHien "nguoiThucHien";
  // Target field: MA_BENH - Mã bệnh liên quan FHIR path: VNCoreCondition.code | VNCoreClaim.diagnosis.diagnosisCodeableConcept
  sourceBundle.entry 0..* as maBenhSource -> targetRow.maBenh "maBenh";
  // Target field: MA_BENH_YHCT - Mã bệnh y học cổ truyền FHIR path: VNCoreClaim.diagnosis.diagnosisCodeableConcept.coding[yhct].code | VNCoreCondition.code.coding[yhct].code
  sourceBundle.entry 0..* as maBenhYhctSource -> targetRow.maBenhYhct "maBenhYhct";
  // Target field: NGAY_YL - Ngày y lệnh FHIR path: VNCoreServiceRequest.authoredOn | VNCoreProcedure.basedOn.resolve().authoredOn
  sourceBundle.entry 0..* as ngayYlSource -> targetRow.ngayYl "ngayYl";
  // Target field: NGAY_TH_YL - Ngày thực hiện y lệnh FHIR path: VNCoreProcedure.performedDateTime | VNCoreServiceRequest.occurrenceDateTime
  sourceBundle.entry 0..* as ngayThYlSource -> targetRow.ngayThYl "ngayThYl";
  // Target field: NGAY_KQ - Ngày kết quả FHIR path: VNCoreDiagnosticReport.issued | VNCoreObservationLab.effectiveDateTime Mapping note: Conditionally required except for bed-day MA_NHOM values 14, 15, 16.
  sourceBundle.entry 0..* as ngayKqSource -> targetRow.ngayKq "ngayKq";
  // Target field: MA_PTTT - Mã phẫu thuật/thủ thuật FHIR path: VNCoreClaim.procedure.procedureCodeableConcept | VNCoreProcedure.code
  sourceBundle.entry 0..* as maPtttSource -> targetRow.maPttt "maPttt";
  // Target field: VET_THUONG_TP - Vết thương tái phát FHIR path: VNCoreClaim.item[serviceLine].extension[recurrentWoundBenefit].valueBoolean | VNCoreExplanationOfBenefit.item[serviceLine].extension[recurrentWoundBenefit].valueBoolean Mapping note: Exporter emits literal `1` only when the line-level recurrentWoundBenefit flag is true; this is not a diagnosis recurrence code.
  sourceBundle.entry 0..* as vetThuongTpSource -> targetRow.vetThuongTp "vetThuongTp";
  // Target field: PP_VO_CAM - Phương pháp vô cảm FHIR path: VNCoreProcedure.extension[anesthesiaMethod] | VNCoreClaim.item.where(category!='8').extension[anesthesiaMethod] | binding vn-anesthesia-method-vs (VNAnesthesiaMethodCS) Mapping note: Mã phương pháp vô cảm trong PT-TT: 1=gây mê, 2=gây tê, 3=châm tê, 4=vô cảm khác (QĐ 3176/QĐ-BYT); chỉ bắt buộc khi PT-TT có dùng phương pháp vô cảm → 0..1. CodeSystem đích VNAnesthesiaMethodCS (vn-anesthesia-method-cs) đã được tạo — binding tới ValueSet vn-anesthesia-method-vs trên future extension anesthesiaMethod của Procedure; bổ sung host Claim.item.extension khi ràng buộc max-cardinality (MR) !=1 của extension được sửa.
  sourceBundle.entry 0..* as ppVoCamSource -> targetRow.ppVoCam "ppVoCam";
  // Target field: VI_TRI_TH_DVKT - Vị trí thực hiện DVKT FHIR path: VNCoreProcedure.bodySite | VNCoreServiceRequest.bodySite
  sourceBundle.entry 0..* as viTriThDvktSource -> targetRow.viTriThDvkt "viTriThDvkt";
  // Target field: MA_MAY - Mã máy FHIR path: VNCoreDevice.identifier.value
  sourceBundle.entry 0..* as maMaySource -> targetRow.maMay "maMay";
  // Target field: MA_HIEU_SP - Mã hiệu sản phẩm FHIR path: VNCoreDevice.deviceName.name | VNCoreDevice.modelNumber
  sourceBundle.entry 0..* as maHieuSpSource -> targetRow.maHieuSp "maHieuSp";
  // Target field: TAI_SU_DUNG - Tái sử dụng FHIR path: VNCoreDeviceUseStatement.note | future reusable-device extension
  sourceBundle.entry 0..* as taiSuDungSource -> targetRow.taiSuDung "taiSuDung";
}